Completed
Pull Request — develop (#207)
by Franck
08:43 queued 01:46
created

Content::writeShapePic()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 42
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 4.0005

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 42
ccs 30
cts 31
cp 0.9677
rs 8.5806
cc 4
eloc 30
nc 6
nop 2
crap 4.0005
1
<?php
2
3
namespace PhpOffice\PhpPresentation\Writer\ODPresentation;
4
5
use PhpOffice\Common\Adapter\Zip\ZipInterface;
6
use PhpOffice\Common\Drawing as CommonDrawing;
7
use PhpOffice\Common\Text;
8
use PhpOffice\Common\XMLWriter;
9
use PhpOffice\PhpPresentation\Shape\Comment;
10
use PhpOffice\PhpPresentation\Slide;
11
use PhpOffice\PhpPresentation\Shape\AbstractDrawing;
12
use PhpOffice\PhpPresentation\Shape\Chart;
13
use PhpOffice\PhpPresentation\Shape\Drawing as ShapeDrawing;
14
use PhpOffice\PhpPresentation\Shape\Group;
15
use PhpOffice\PhpPresentation\Shape\Line;
16
use PhpOffice\PhpPresentation\Shape\RichText\BreakElement;
17
use PhpOffice\PhpPresentation\Shape\RichText\Run;
18
use PhpOffice\PhpPresentation\Shape\RichText\TextElement;
19
use PhpOffice\PhpPresentation\Shape\RichText;
20
use PhpOffice\PhpPresentation\Shape\Table;
21
use PhpOffice\PhpPresentation\Slide\Note;
22
use PhpOffice\PhpPresentation\Slide\Transition;
23
use PhpOffice\PhpPresentation\Style\Alignment;
24
use PhpOffice\PhpPresentation\Style\Border;
25
use PhpOffice\PhpPresentation\Style\Fill;
26
use PhpOffice\PhpPresentation\Style\Shadow;
27
use PhpOffice\PhpPresentation\Writer\ODPresentation;
28
29
class Content extends AbstractDecoratorWriter
30
{
31
    /**
32
     * Stores bullet styles for text shapes that include lists.
33
     *
34
     * @var []
35
     */
36
    protected $arrStyleBullet    = array();
37
38
    /**
39
     * Stores paragraph information for text shapes.
40
     *
41
     * @var array
42
     */
43
    protected $arrStyleParagraph = array();
44
45
    /**
46
     * Stores font styles for text shapes that include lists.
47
     *
48
     * @var Run[]
49
     */
50
    protected $arrStyleTextFont  = array();
51
52
    /**
53
     * Used to track the current shape ID.
54
     *
55
     * @var integer
56
     */
57
    protected $shapeId;
58
59
    /**
60
     * @return ZipInterface
61
     */
62
    public function render()
63 57
    {
64
        $this->getZip()->addFromString('content.xml', $this->writeContent());
65 57
        return $this->getZip();
66 57
    }
67
68
69
70
    /**
71
     * Write content file to XML format
72
     *
73
     * @return string        XML Output
74
     * @throws \Exception
75
     */
76
    public function writeContent()
77 57
    {
78
        // Create XML writer
79
        $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
80 57
        $objWriter->startDocument('1.0', 'UTF-8');
81 57
82
        // office:document-content
83
        $objWriter->startElement('office:document-content');
84 57
        $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
85 57
        $objWriter->writeAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0');
86 57
        $objWriter->writeAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0');
87 57
        $objWriter->writeAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0');
88 57
        $objWriter->writeAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0');
89 57
        $objWriter->writeAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0');
90 57
        $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
91 57
        $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');
92 57
        $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0');
93 57
        $objWriter->writeAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0');
94 57
        $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0');
95 57
        $objWriter->writeAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0');
96 57
        $objWriter->writeAttribute('xmlns:chart', 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0');
97 57
        $objWriter->writeAttribute('xmlns:dr3d', 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0');
98 57
        $objWriter->writeAttribute('xmlns:math', 'http://www.w3.org/1998/Math/MathML');
99 57
        $objWriter->writeAttribute('xmlns:form', 'urn:oasis:names:tc:opendocument:xmlns:form:1.0');
100 57
        $objWriter->writeAttribute('xmlns:script', 'urn:oasis:names:tc:opendocument:xmlns:script:1.0');
101 57
        $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');
102 57
        $objWriter->writeAttribute('xmlns:ooow', 'http://openoffice.org/2004/writer');
103 57
        $objWriter->writeAttribute('xmlns:oooc', 'http://openoffice.org/2004/calc');
104 57
        $objWriter->writeAttribute('xmlns:dom', 'http://www.w3.org/2001/xml-events');
105 57
        $objWriter->writeAttribute('xmlns:xforms', 'http://www.w3.org/2002/xforms');
106 57
        $objWriter->writeAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema');
107 57
        $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
108 57
        $objWriter->writeAttribute('xmlns:smil', 'urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0');
109 57
        $objWriter->writeAttribute('xmlns:anim', 'urn:oasis:names:tc:opendocument:xmlns:animation:1.0');
110 57
        $objWriter->writeAttribute('xmlns:rpt', 'http://openoffice.org/2005/report');
111 57
        $objWriter->writeAttribute('xmlns:of', 'urn:oasis:names:tc:opendocument:xmlns:of:1.2');
112 57
        $objWriter->writeAttribute('xmlns:rdfa', 'http://docs.oasis-open.org/opendocument/meta/rdfa#');
113 57
        $objWriter->writeAttribute('xmlns:field', 'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0');
114 57
        $objWriter->writeAttribute('xmlns:officeooo', 'http://openoffice.org/2009/office');
115 57
        $objWriter->writeAttribute('office:version', '1.2');
116 57
117
        // office:automatic-styles
118
        $objWriter->startElement('office:automatic-styles');
119 57
120
        $this->shapeId    = 0;
121 57
        $incSlide = 0;
122 57
        foreach ($this->getPresentation()->getAllSlides() as $pSlide) {
123 57
            // Slides
124
            $this->writeStyleSlide($objWriter, $pSlide, $incSlide);
125 57
126
            // Images
127
            $shapes = $pSlide->getShapeCollection();
128 57
            foreach ($shapes as $shape) {
129 57
                // Increment $this->shapeId
130
                ++$this->shapeId;
131 50
132
                // Check type
133
                if ($shape instanceof RichText) {
134 50
                    $this->writeTxtStyle($objWriter, $shape);
135 14
                }
136
                if ($shape instanceof AbstractDrawing) {
0 ignored issues
show
Bug introduced by
The class PhpOffice\PhpPresentation\Shape\AbstractDrawing does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
137 50
                    $this->writeDrawingStyle($objWriter, $shape);
138 34
                }
139
                if ($shape instanceof Line) {
140 50
                    $this->writeLineStyle($objWriter, $shape);
141 1
                }
142
                if ($shape instanceof Table) {
143 50
                    $this->writeTableStyle($objWriter, $shape);
144 7
                }
145
                if ($shape instanceof Group) {
146 50
                    $this->writeGroupStyle($objWriter, $shape);
147 50
                }
148
            }
149
150
            $incSlide++;
151 57
        }
152
        // Style : Bullet
153
        if (!empty($this->arrStyleBullet)) {
154 57
            foreach ($this->arrStyleBullet as $key => $item) {
155 14
                $oStyle   = $item['oStyle'];
156 14
                $arrLevel = explode(';', $item['level']);
157 14
                // style:style
158
                $objWriter->startElement('text:list-style');
159 14
                $objWriter->writeAttribute('style:name', 'L_' . $key);
160 14
                foreach ($arrLevel as $level) {
161 14
                    if ($level != '') {
162 14
                        $oAlign = $item['oAlign_' . $level];
163 14
                        // text:list-level-style-bullet
164
                        $objWriter->startElement('text:list-level-style-bullet');
165 14
                        $objWriter->writeAttribute('text:level', $level + 1);
166 14
                        $objWriter->writeAttribute('text:bullet-char', $oStyle->getBulletChar());
167 14
                        // style:list-level-properties
168
                        $objWriter->startElement('style:list-level-properties');
169 14
                        if ($oAlign->getIndent() < 0) {
170 14
                            $objWriter->writeAttribute('text:space-before', CommonDrawing::pixelsToCentimeters($oAlign->getMarginLeft() - (-1 * $oAlign->getIndent())) . 'cm');
171 1
                            $objWriter->writeAttribute('text:min-label-width', CommonDrawing::pixelsToCentimeters(-1 * $oAlign->getIndent()) . 'cm');
172 1
                        } else {
173
                            $objWriter->writeAttribute('text:space-before', (CommonDrawing::pixelsToCentimeters($oAlign->getMarginLeft() - $oAlign->getIndent())) . 'cm');
174 13
                            $objWriter->writeAttribute('text:min-label-width', CommonDrawing::pixelsToCentimeters($oAlign->getIndent()) . 'cm');
175 13
                        }
176
177
                        $objWriter->endElement();
178 14
                        // style:text-properties
179
                        $objWriter->startElement('style:text-properties');
180 14
                        $objWriter->writeAttribute('fo:font-family', $oStyle->getBulletFont());
181 14
                        $objWriter->writeAttribute('style:font-family-generic', 'swiss');
182 14
                        $objWriter->writeAttribute('style:use-window-font-color', 'true');
183 14
                        $objWriter->writeAttribute('fo:font-size', '100');
184 14
                        $objWriter->endElement();
185 14
                        $objWriter->endElement();
186 14
                    }
187
                }
188
                $objWriter->endElement();
189 14
            }
190
        }
191
        // Style : Paragraph
192
        if (!empty($this->arrStyleParagraph)) {
193 57
            foreach ($this->arrStyleParagraph as $key => $item) {
194 14
                // style:style
195
                $objWriter->startElement('style:style');
196 14
                $objWriter->writeAttribute('style:name', 'P_' . $key);
197 14
                $objWriter->writeAttribute('style:family', 'paragraph');
198 14
                // style:paragraph-properties
199
                $objWriter->startElement('style:paragraph-properties');
200 14
                switch ($item->getAlignment()->getHorizontal()) {
201 14
                    case Alignment::HORIZONTAL_LEFT:
202 14
                        $objWriter->writeAttribute('fo:text-align', 'left');
203 14
                        break;
204 14
                    case Alignment::HORIZONTAL_RIGHT:
205 1
                        $objWriter->writeAttribute('fo:text-align', 'right');
206 1
                        break;
207 1
                    case Alignment::HORIZONTAL_CENTER:
208 1
                        $objWriter->writeAttribute('fo:text-align', 'center');
209 1
                        break;
210 1
                    case Alignment::HORIZONTAL_JUSTIFY:
211 1
                        $objWriter->writeAttribute('fo:text-align', 'justify');
212 1
                        break;
213 1
                    case Alignment::HORIZONTAL_DISTRIBUTED:
214 1
                        $objWriter->writeAttribute('fo:text-align', 'justify');
215 1
                        break;
216 1
                    default:
217
                        $objWriter->writeAttribute('fo:text-align', 'left');
218 1
                        break;
219 1
                }
220
                $objWriter->endElement();
221 14
                $objWriter->endElement();
222 14
            }
223
        }
224
        // Style : Text : Font
225
        if (!empty($this->arrStyleTextFont)) {
226 57
            foreach ($this->arrStyleTextFont as $key => $item) {
227 10
                // style:style
228
                $objWriter->startElement('style:style');
229 10
                $objWriter->writeAttribute('style:name', 'T_' . $key);
230 10
                $objWriter->writeAttribute('style:family', 'text');
231 10
                // style:text-properties
232
                $objWriter->startElement('style:text-properties');
233 10
                $objWriter->writeAttribute('fo:color', '#' . $item->getFont()->getColor()->getRGB());
234 10
                $objWriter->writeAttribute('fo:font-family', $item->getFont()->getName());
235 10
                $objWriter->writeAttribute('fo:font-size', $item->getFont()->getSize() . 'pt');
236 10
                // @todo : fo:font-style
237
                if ($item->getFont()->isBold()) {
238 10
                    $objWriter->writeAttribute('fo:font-weight', 'bold');
239 1
                }
240
                $objWriter->writeAttribute('fo:language', ($item->getLanguage() ? $item->getLanguage() : 'en-US'));
241 10
242
                // @todo : style:text-underline-style
243
                $objWriter->endElement();
244 10
                $objWriter->endElement();
245 10
            }
246
        }
247
        $objWriter->endElement();
248 57
249
        //===============================================
250
        // Body
251
        //===============================================
252
        // office:body
253
        $objWriter->startElement('office:body');
254 57
        // office:presentation
255
        $objWriter->startElement('office:presentation');
256 57
257
        // Write slides
258
        $slideCount = $this->getPresentation()->getSlideCount();
259 57
        $this->shapeId    = 0;
260 57
        for ($i = 0; $i < $slideCount; ++$i) {
261 57
            $pSlide = $this->getPresentation()->getSlide($i);
262 57
            $objWriter->startElement('draw:page');
263 57
            $name = $pSlide->getName();
264 57
            if (!is_null($name)) {
265 57
                $objWriter->writeAttribute('draw:name', $name);
266 1
            }
267
            $objWriter->writeAttribute('draw:master-page-name', 'Standard');
268 57
            $objWriter->writeAttribute('draw:style-name', 'stylePage' . $i);
269 57
            // Images
270
            $shapes = $pSlide->getShapeCollection();
271 57
            foreach ($shapes as $shape) {
272 57
                // Increment $this->shapeId
273
                ++$this->shapeId;
274 50
275
                // Check type
276
                if ($shape instanceof RichText) {
277 50
                    $this->writeShapeTxt($objWriter, $shape);
278 14
                } elseif ($shape instanceof Table) {
279
                    $this->writeShapeTable($objWriter, $shape);
280 7
                } elseif ($shape instanceof Line) {
281
                    $this->writeShapeLine($objWriter, $shape);
282 1
                } elseif ($shape instanceof Chart) {
283
                    $this->writeShapeChart($objWriter, $shape);
284 21
                } elseif ($shape instanceof ShapeDrawing\AbstractDrawingAdapter) {
285
                    $this->writeShapeDrawing($objWriter, $shape);
286 8
                } elseif ($shape instanceof Group) {
287
                    $this->writeShapeGroup($objWriter, $shape);
288 1
                } elseif ($shape instanceof Comment) {
289
                    $this->writeShapeComment($objWriter, $shape);
290 50
                }
291
            }
292
            // Slide Note
293
            if ($pSlide->getNote() instanceof Note) {
294 57
                $this->writeSlideNote($objWriter, $pSlide->getNote());
295 57
            }
296
297
            $objWriter->endElement();
298 57
        }
299
300
        if ($this->getPresentation()->getPresentationProperties()->isLoopContinuouslyUntilEsc()) {
301 57
            $objWriter->startElement('presentation:settings');
302
            $objWriter->writeAttribute('presentation:endless', 'true');
303
            $objWriter->writeAttribute('presentation:pause', 'P0s');
304
            $objWriter->writeAttribute('presentation:mouse-visible', 'false');
305
            $objWriter->endElement();
306
        }
307
        // > office:presentation
308
        $objWriter->endElement();
309 57
        // > office:body
310
        $objWriter->endElement();
311 57
        // > office:document-content
312
        $objWriter->endElement();
313 57
314
        // Return
315
        return $objWriter->getData();
316 57
    }
317
318
    /**
319
     * Write picture
320
     *
321
     * @param \PhpOffice\Common\XMLWriter $objWriter
322
     * @param \PhpOffice\PhpPresentation\Shape\AbstractDrawing $shape
323
     */
324
    public function writeShapeDrawing(XMLWriter $objWriter, ShapeDrawing\AbstractDrawingAdapter $shape)
325 9
    {
326
        // draw:frame
327
        $objWriter->startElement('draw:frame');
328 9
        $objWriter->writeAttribute('draw:name', $shape->getName());
329 9
        $objWriter->writeAttribute('svg:width', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getWidth()), 3) . 'cm');
330 9
        $objWriter->writeAttribute('svg:height', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getHeight()), 3) . 'cm');
331 9
        $objWriter->writeAttribute('svg:x', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm');
332 9
        $objWriter->writeAttribute('svg:y', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm');
333 9
        $objWriter->writeAttribute('draw:style-name', 'gr' . $this->shapeId);
334 9
        // draw:image
335
        $objWriter->startElement('draw:image');
336 9
        if ($shape instanceof ShapeDrawing\AbstractDrawingAdapter) {
337 9
            $objWriter->writeAttribute('xlink:href', 'Pictures/' . $shape->getIndexedFilename());
338 8
        }
339
        $objWriter->writeAttribute('xlink:type', 'simple');
340 1
        $objWriter->writeAttribute('xlink:show', 'embed');
341
        $objWriter->writeAttribute('xlink:actuate', 'onLoad');
342 9
        $objWriter->writeElement('text:p');
343 9
        $objWriter->endElement();
344 9
345 9
        if ($shape->hasHyperlink()) {
346 9
            // office:event-listeners
347
            $objWriter->startElement('office:event-listeners');
348 9
            // presentation:event-listener
349
            $objWriter->startElement('presentation:event-listener');
350 2
            $objWriter->writeAttribute('script:event-name', 'dom:click');
351
            $objWriter->writeAttribute('presentation:action', 'show');
352 2
            $objWriter->writeAttribute('xlink:href', $shape->getHyperlink()->getUrl());
353 2
            $objWriter->writeAttribute('xlink:type', 'simple');
354 2
            $objWriter->writeAttribute('xlink:show', 'embed');
355 2
            $objWriter->writeAttribute('xlink:actuate', 'onRequest');
356 2
            // > presentation:event-listener
357 2
            $objWriter->endElement();
358 2
            // > office:event-listeners
359
            $objWriter->endElement();
360 2
        }
361
362 2
        $objWriter->endElement();
363
    }
364
365 9
    /**
366 9
     * Write text
367
     *
368
     * @param \PhpOffice\Common\XMLWriter $objWriter
369
     * @param \PhpOffice\PhpPresentation\Shape\RichText $shape
370
     */
371
    public function writeShapeTxt(XMLWriter $objWriter, RichText $shape)
372
    {
373
        // draw:frame
374 15
        $objWriter->startElement('draw:frame');
375
        $objWriter->writeAttribute('draw:style-name', 'gr' . $this->shapeId);
376
        $objWriter->writeAttribute('svg:width', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getWidth()), 3) . 'cm');
377 15
        $objWriter->writeAttribute('svg:height', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getHeight()), 3) . 'cm');
378 15
        $objWriter->writeAttribute('svg:x', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm');
379 15
        $objWriter->writeAttribute('svg:y', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm');
380 15
        // draw:text-box
381 15
        $objWriter->startElement('draw:text-box');
382 15
383
        $paragraphs             = $shape->getParagraphs();
384 15
        $paragraphId            = 0;
385
        $sCstShpLastBullet      = '';
386 15
        $iCstShpLastBulletLvl   = 0;
387 15
        $bCstShpHasBullet       = false;
388 15
389 15
        foreach ($paragraphs as $paragraph) {
390 15
            // Close the bullet list
391
            if ($sCstShpLastBullet != 'bullet' && $bCstShpHasBullet === true) {
392 15
                for ($iInc = $iCstShpLastBulletLvl; $iInc >= 0; $iInc--) {
393
                    // text:list-item
394 15
                    $objWriter->endElement();
395
                    // text:list
396
                    $objWriter->endElement();
397
                }
398
            }
399
            //===============================================
400
            // Paragraph
401
            //===============================================
402
            if ($paragraph->getBulletStyle()->getBulletType() == 'none') {
403
                ++$paragraphId;
404
                // text:p
405 15
                $objWriter->startElement('text:p');
406 12
                $objWriter->writeAttribute('text:style-name', 'P_' . $paragraph->getHashCode());
407
408 12
                // Loop trough rich text elements
409 12
                $richtexts  = $paragraph->getRichTextElements();
410
                $richtextId = 0;
411
                foreach ($richtexts as $richtext) {
412 12
                    ++$richtextId;
413 12
                    if ($richtext instanceof TextElement || $richtext instanceof Run) {
414 12
                        // text:span
415 6
                        $objWriter->startElement('text:span');
416 6
                        if ($richtext instanceof Run) {
417
                            $objWriter->writeAttribute('text:style-name', 'T_' . $richtext->getHashCode());
418 6
                        }
419 6
                        if ($richtext->hasHyperlink() === true && $richtext->getHyperlink()->getUrl() != '') {
420 6
                            // text:a
421
                            $objWriter->startElement('text:a');
422 6
                            $objWriter->writeAttribute('xlink:href', $richtext->getHyperlink()->getUrl());
423
                            $objWriter->text($richtext->getText());
424 1
                            $objWriter->endElement();
425 1
                        } else {
426 1
                            $objWriter->text($richtext->getText());
427 1
                        }
428
                        $objWriter->endElement();
429 6
                    } elseif ($richtext instanceof BreakElement) {
430
                        // text:span
431 6
                        $objWriter->startElement('text:span');
432
                        // text:line-break
433
                        $objWriter->startElement('text:line-break');
434 1
                        $objWriter->endElement();
435
                        $objWriter->endElement();
436 1
                    } else {
437 1
                        //echo '<pre>'.print_r($richtext, true).'</pre>';
438 1
                    }
439 6
                }
440
                $objWriter->endElement();
441
                //===============================================
442
                // Bullet list
443 12
                //===============================================
444
            } elseif ($paragraph->getBulletStyle()->getBulletType() == 'bullet') {
445
                $bCstShpHasBullet = true;
446
                // Open the bullet list
447 3
                if ($sCstShpLastBullet != 'bullet' || ($sCstShpLastBullet == $paragraph->getBulletStyle()->getBulletType() && $iCstShpLastBulletLvl < $paragraph->getAlignment()->getLevel())) {
448 3
                    // text:list
449
                    $objWriter->startElement('text:list');
450 3
                    $objWriter->writeAttribute('text:style-name', 'L_' . $paragraph->getBulletStyle()->getHashCode());
451
                }
452 3
                if ($sCstShpLastBullet == 'bullet') {
453 3
                    if ($iCstShpLastBulletLvl == $paragraph->getAlignment()->getLevel()) {
454
                        // text:list-item
455 3
                        $objWriter->endElement();
456 2
                    } elseif ($iCstShpLastBulletLvl > $paragraph->getAlignment()->getLevel()) {
457
                        // text:list-item
458 2
                        $objWriter->endElement();
459 1
                        // text:list
460
                        $objWriter->endElement();
461 1
                        // text:list-item
462
                        $objWriter->endElement();
463 1
                    }
464
                }
465 1
466
                // text:list-item
467
                $objWriter->startElement('text:list-item');
468
                ++$paragraphId;
469
                // text:p
470 3
                $objWriter->startElement('text:p');
471 3
                $objWriter->writeAttribute('text:style-name', 'P_' . $paragraph->getHashCode());
472
473 3
                // Loop trough rich text elements
474 3
                $richtexts  = $paragraph->getRichTextElements();
475
                $richtextId = 0;
476
                foreach ($richtexts as $richtext) {
477 3
                    ++$richtextId;
478 3
                    if ($richtext instanceof TextElement || $richtext instanceof Run) {
479 3
                        // text:span
480 3
                        $objWriter->startElement('text:span');
481 3
                        if ($richtext instanceof Run) {
482
                            $objWriter->writeAttribute('text:style-name', 'T_' . $richtext->getHashCode());
483 3
                        }
484 3
                        if ($richtext->hasHyperlink() === true && $richtext->getHyperlink()->getUrl() != '') {
485 3
                            // text:a
486
                            $objWriter->startElement('text:a');
487 3
                            $objWriter->writeAttribute('xlink:href', $richtext->getHyperlink()->getUrl());
488
                            $objWriter->text($richtext->getText());
489 1
                            $objWriter->endElement();
490 1
                        } else {
491 1
                            $objWriter->text($richtext->getText());
492 1
                        }
493
                        $objWriter->endElement();
494 3
                    } elseif ($richtext instanceof BreakElement) {
495
                        // text:span
496 3
                        $objWriter->startElement('text:span');
497
                        // text:line-break
498
                        $objWriter->startElement('text:line-break');
499 1
                        $objWriter->endElement();
500
                        $objWriter->endElement();
501 1
                    } else {
502 1
                        //echo '<pre>'.print_r($richtext, true).'</pre>';
503 1
                    }
504 3
                }
505
                $objWriter->endElement();
506
            }
507
            $sCstShpLastBullet      = $paragraph->getBulletStyle()->getBulletType();
508 3
            $iCstShpLastBulletLvl = $paragraph->getAlignment()->getLevel();
509
        }
510 15
511 15
        // Close the bullet list
512
        if ($sCstShpLastBullet == 'bullet' && $bCstShpHasBullet === true) {
513
            for ($iInc = $iCstShpLastBulletLvl; $iInc >= 0; $iInc--) {
514
                // text:list-item
515 15
                $objWriter->endElement();
516 3
                // text:list
517
                $objWriter->endElement();
518 3
            }
519
        }
520 3
521
        // > draw:text-box
522
        $objWriter->endElement();
523
        // > draw:frame
524
        $objWriter->endElement();
525 15
    }
526
    /**
527 15
     * Write Comment
528 15
     * @param XMLWriter $objWriter
529
     * @param Comment $oShape
530
     */
531
    public function writeShapeComment(XMLWriter $objWriter, Comment $oShape)
532
    {
533
        // officeooo:annotation
534 2
        $objWriter->startElement('officeooo:annotation');
535
        $objWriter->writeAttribute('svg:x', number_format(CommonDrawing::pixelsToCentimeters($oShape->getOffsetX()), 2, '.', '').'cm');
536
        $objWriter->writeAttribute('svg:y', number_format(CommonDrawing::pixelsToCentimeters($oShape->getOffsetY()), 2, '.', '').'cm');
537 2
538 2
        if ($oShape->getAuthor() instanceof Comment\Author) {
539 2
            $objWriter->writeElement('dc:creator', $oShape->getAuthor()->getName());
540
        }
541 2
        $objWriter->writeElement('dc:date', date('Y-m-d\TH:i:s', $oShape->getDate()));
542 1
        $objWriter->writeElement('text:p', $oShape->getText());
543
544 2
        // ## officeooo:annotation
545 2
        $objWriter->endElement();
546
    }
547
548 2
    /**
549 2
     * @param XMLWriter $objWriter
550
     * @param Line $shape
551
     */
552
    public function writeShapeLine(XMLWriter $objWriter, Line $shape)
553
    {
554
        // draw:line
555 1
        $objWriter->startElement('draw:line');
556
        $objWriter->writeAttribute('draw:style-name', 'gr' . $this->shapeId);
557
        $objWriter->writeAttribute('svg:x1', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm');
558 1
        $objWriter->writeAttribute('svg:y1', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm');
559 1
        $objWriter->writeAttribute('svg:x2', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetX()+$shape->getWidth()), 3) . 'cm');
560 1
        $objWriter->writeAttribute('svg:y2', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetY()+$shape->getHeight()), 3) . 'cm');
561 1
562 1
        // text:p
563 1
        $objWriter->writeElement('text:p');
564
565
        $objWriter->endElement();
566 1
    }
567
568 1
    /**
569 1
     * Write table Shape
570
     * @param XMLWriter $objWriter
571
     * @param Table $shape
572
     */
573
    public function writeShapeTable(XMLWriter $objWriter, Table $shape)
574
    {
575
        // draw:frame
576 7
        $objWriter->startElement('draw:frame');
577
        $objWriter->writeAttribute('svg:x', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm');
578
        $objWriter->writeAttribute('svg:y', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm');
579 7
        $objWriter->writeAttribute('svg:height', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getHeight()), 3) . 'cm');
580 7
        $objWriter->writeAttribute('svg:width', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getWidth()), 3) . 'cm');
581 7
582 7
        // table:table
583 7
        $objWriter->startElement('table:table');
584
585
        foreach ($shape->getRows() as $keyRow => $shapeRow) {
586 7
            // table:table-row
587
            $objWriter->startElement('table:table-row');
588 7
            $objWriter->writeAttribute('table:style-name', 'gr'.$this->shapeId.'r'.$keyRow);
589
            //@todo getFill
590 6
591 6
            $numColspan = 0;
592
            foreach ($shapeRow->getCells() as $keyCell => $shapeCell) {
593
                if ($numColspan == 0) {
594 6
                    // table:table-cell
595 6
                    $objWriter->startElement('table:table-cell');
596 6
                    $objWriter->writeAttribute('table:style-name', 'gr' . $this->shapeId.'r'.$keyRow.'c'.$keyCell);
597
                    if ($shapeCell->getColspan() > 1) {
598 6
                        $objWriter->writeAttribute('table:number-columns-spanned', $shapeCell->getColspan());
599 6
                        $numColspan = $shapeCell->getColspan() - 1;
600 6
                    }
601 1
602 1
                    // text:p
603
                    $objWriter->startElement('text:p');
604
605
                    // text:span
606 6
                    foreach ($shapeCell->getParagraphs() as $shapeParagraph) {
607
                        foreach ($shapeParagraph->getRichTextElements() as $shapeRichText) {
608
                            if ($shapeRichText instanceof TextElement || $shapeRichText instanceof Run) {
609 6
                                // text:span
610 6
                                $objWriter->startElement('text:span');
611 2
                                if ($shapeRichText instanceof Run) {
612
                                    $objWriter->writeAttribute('text:style-name', 'T_' . $shapeRichText->getHashCode());
613 2
                                }
614 2
                                if ($shapeRichText->hasHyperlink() === true && $shapeRichText->getHyperlink()->getUrl() != '') {
615 2
                                    // text:a
616
                                    $objWriter->startElement('text:a');
617 2
                                    $objWriter->writeAttribute('xlink:href', $shapeRichText->getHyperlink()->getUrl());
618
                                    $objWriter->text($shapeRichText->getText());
619 1
                                    $objWriter->endElement();
620 1
                                } else {
621 1
                                    $objWriter->text($shapeRichText->getText());
622 1
                                }
623
                                $objWriter->endElement();
624 1
                            } elseif ($shapeRichText instanceof BreakElement) {
625
                                // text:span
626 2
                                $objWriter->startElement('text:span');
627
                                // text:line-break
628
                                $objWriter->startElement('text:line-break');
629 1
                                $objWriter->endElement();
630
                                $objWriter->endElement();
631 1
                            }
632 1
                        }
633 6
                    }
634
635
                    // > text:p
636
                    $objWriter->endElement();
637
638
                    // > table:table-cell
639 6
                    $objWriter->endElement();
640
                } else {
641
                    // table:covered-table-cell
642 6
                    $objWriter->writeElement('table:covered-table-cell');
643
                    $numColspan--;
644
                }
645 1
            }
646 6
            // > table:table-row
647
            $objWriter->endElement();
648
        }
649
        // > table:table
650 6
        $objWriter->endElement();
651
        // > draw:frame
652
        $objWriter->endElement();
653 7
    }
654
655 7
    /**
656 7
     * Write table Chart
657
     * @param XMLWriter $objWriter
658
     * @param Chart $shape
659
     * @throws \Exception
660
     */
661
    public function writeShapeChart(XMLWriter $objWriter, Chart $shape)
662
    {
663
        $arrayChart = $this->getArrayChart();
664 21
        $arrayChart[$this->shapeId] = $shape;
665
        $this->setArrayChart($arrayChart);
666 21
667 21
        // draw:frame
668 21
        $objWriter->startElement('draw:frame');
669
        $objWriter->writeAttribute('draw:name', $shape->getTitle()->getText());
670
        $objWriter->writeAttribute('svg:x', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetX()), 3) . 'cm');
671 21
        $objWriter->writeAttribute('svg:y', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getOffsetY()), 3) . 'cm');
672 21
        $objWriter->writeAttribute('svg:height', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getHeight()), 3) . 'cm');
673 21
        $objWriter->writeAttribute('svg:width', Text::numberFormat(CommonDrawing::pixelsToCentimeters($shape->getWidth()), 3) . 'cm');
674 21
675 21
        // draw:object
676 21
        $objWriter->startElement('draw:object');
677
        $objWriter->writeAttribute('xlink:href', './Object '.$this->shapeId);
678
        $objWriter->writeAttribute('xlink:type', 'simple');
679 21
        $objWriter->writeAttribute('xlink:show', 'embed');
680 21
681 21
        // > draw:object
682 21
        $objWriter->endElement();
683
        // > draw:frame
684
        $objWriter->endElement();
685 21
    }
686
687 21
    /**
688 21
     * Writes a group of shapes
689
     *
690
     * @param XMLWriter $objWriter
691
     * @param Group $group
692
     */
693
    public function writeShapeGroup(XMLWriter $objWriter, Group $group)
694
    {
695
        // draw:g
696 1
        $objWriter->startElement('draw:g');
697
698
        $shapes = $group->getShapeCollection();
699 1
        foreach ($shapes as $shape) {
700
            // Increment $this->shapeId
701 1
            ++$this->shapeId;
702 1
703
            // Check type
704 1
            if ($shape instanceof RichText) {
705
                $this->writeShapeTxt($objWriter, $shape);
706
            } elseif ($shape instanceof Table) {
707 1
                $this->writeShapeTable($objWriter, $shape);
708
            } elseif ($shape instanceof Line) {
709
                $this->writeShapeLine($objWriter, $shape);
710
            } elseif ($shape instanceof Chart) {
711
                $this->writeShapeChart($objWriter, $shape);
712
            } elseif ($shape instanceof ShapeDrawing\AbstractDrawingAdapter) {
713
                $this->writeShapeDrawing($objWriter, $shape);
714
            } elseif ($shape instanceof Group) {
715
                $this->writeShapeGroup($objWriter, $shape);
716 1
            }
717
        }
718 1
719
        $objWriter->endElement(); // draw:g
720
    }
721
722 1
    /**
723 1
     * Writes the style information for a group of shapes
724
     *
725
     * @param XMLWriter $objWriter
726
     * @param Group $group
727
     */
728
    public function writeGroupStyle(XMLWriter $objWriter, Group $group)
729
    {
730
        $shapes = $group->getShapeCollection();
731 1
        foreach ($shapes as $shape) {
732
            // Increment $this->shapeId
733 1
            ++$this->shapeId;
734 1
735
            // Check type
736 1
            if ($shape instanceof RichText) {
737
                $this->writeTxtStyle($objWriter, $shape);
738
            }
739 1
            if ($shape instanceof AbstractDrawing) {
0 ignored issues
show
Bug introduced by
The class PhpOffice\PhpPresentation\Shape\AbstractDrawing does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
740
                $this->writeDrawingStyle($objWriter, $shape);
741
            }
742 1
            if ($shape instanceof Line) {
743 1
                $this->writeLineStyle($objWriter, $shape);
744
            }
745 1
            if ($shape instanceof Table) {
746
                $this->writeTableStyle($objWriter, $shape);
747
            }
748 1
        }
749 1
    }
750
751
    /**
752 1
     * Write the default style information for a RichText shape
753
     *
754
     * @param \PhpOffice\Common\XMLWriter $objWriter
755
     * @param \PhpOffice\PhpPresentation\Shape\RichText $shape
756
     */
757
    public function writeTxtStyle(XMLWriter $objWriter, RichText $shape)
758
    {
759
        // style:style
760 14
        $objWriter->startElement('style:style');
761
        $objWriter->writeAttribute('style:name', 'gr' . $this->shapeId);
762
        $objWriter->writeAttribute('style:family', 'graphic');
763 14
        $objWriter->writeAttribute('style:parent-style-name', 'standard');
764 14
        // style:graphic-properties
765 14
        $objWriter->startElement('style:graphic-properties');
766 14
        if ($shape->getShadow()->isVisible()) {
767
            $this->writeStylePartShadow($objWriter, $shape->getShadow());
768 14
        }
769 14
        if (is_bool($shape->hasAutoShrinkVertical())) {
770 1
            $objWriter->writeAttribute('draw:auto-grow-height', var_export($shape->hasAutoShrinkVertical(), true));
771
        }
772 14
        if (is_bool($shape->hasAutoShrinkHorizontal())) {
773 1
            $objWriter->writeAttribute('draw:auto-grow-width', var_export($shape->hasAutoShrinkHorizontal(), true));
774
        }
775 14
        // Fill
776 1
        switch ($shape->getFill()->getFillType()) {
777
            case Fill::FILL_GRADIENT_LINEAR:
778
            case Fill::FILL_GRADIENT_PATH:
779 14
                $objWriter->writeAttribute('draw:fill', 'gradient');
780 14
                $objWriter->writeAttribute('draw:fill-gradient-name', 'gradient_'.$shape->getFill()->getHashCode());
781 13
                break;
782 1
            case Fill::FILL_SOLID:
783 1
                $objWriter->writeAttribute('draw:fill', 'solid');
784 1
                $objWriter->writeAttribute('draw:fill-color', '#'.$shape->getFill()->getStartColor()->getRGB());
785 13
                break;
786 1
            case Fill::FILL_NONE:
787 1
            default:
788 1
                $objWriter->writeAttribute('draw:fill', 'none');
789 12
                $objWriter->writeAttribute('draw:fill-color', '#'.$shape->getFill()->getStartColor()->getRGB());
790
                break;
791 12
        }
792 12
        // Border
793 12
        if ($shape->getBorder()->getLineStyle() == Border::LINE_NONE) {
794
            $objWriter->writeAttribute('draw:stroke', 'none');
795
        } else {
796 14
            $objWriter->writeAttribute('svg:stroke-color', '#'.$shape->getBorder()->getColor()->getRGB());
797 13
            $objWriter->writeAttribute('svg:stroke-width', number_format(CommonDrawing::pointsToCentimeters($shape->getBorder()->getLineWidth()), 3, '.', '').'cm');
798
            switch ($shape->getBorder()->getDashStyle()) {
799 2
                case Border::DASH_SOLID:
800 2
                    $objWriter->writeAttribute('draw:stroke', 'solid');
801 2
                    break;
802 2
                case Border::DASH_DASH:
803 1
                case Border::DASH_DASHDOT:
804 1
                case Border::DASH_DOT:
805 2
                case Border::DASH_LARGEDASH:
806 1
                case Border::DASH_LARGEDASHDOT:
807 1
                case Border::DASH_LARGEDASHDOTDOT:
808 1
                case Border::DASH_SYSDASH:
809 1
                case Border::DASH_SYSDASHDOT:
810 1
                case Border::DASH_SYSDASHDOTDOT:
811 1
                case Border::DASH_SYSDOT:
812 1
                    $objWriter->writeAttribute('draw:stroke', 'dash');
813 1
                    $objWriter->writeAttribute('draw:stroke-dash', 'strokeDash_'.$shape->getBorder()->getDashStyle());
814 1
                    break;
815 2
                default:
816 2
                    $objWriter->writeAttribute('draw:stroke', 'none');
817 2
                    break;
818
            }
819
        }
820
821
        $objWriter->writeAttribute('fo:wrap-option', 'wrap');
822
        // > style:graphic-properties
823
        $objWriter->endElement();
824 14
        // > style:style
825
        $objWriter->endElement();
826 14
827
        $paragraphs  = $shape->getParagraphs();
828 14
        $paragraphId = 0;
829
        foreach ($paragraphs as $paragraph) {
830 14
            ++$paragraphId;
831 14
832 14
            // Style des paragraphes
833 14
            if (!isset($this->arrStyleParagraph[$paragraph->getHashCode()])) {
834
                $this->arrStyleParagraph[$paragraph->getHashCode()] = $paragraph;
835
            }
836 14
837 14
            // Style des listes
838
            if (!isset($this->arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()])) {
839
                $this->arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['oStyle'] = $paragraph->getBulletStyle();
840
                $this->arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['level']  = '';
841 14
            }
842 14
            if (strpos($this->arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['level'], ';' . $paragraph->getAlignment()->getLevel()) === false) {
843 14
                $this->arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['level'] .= ';' . $paragraph->getAlignment()->getLevel();
844
                $this->arrStyleBullet[$paragraph->getBulletStyle()->getHashCode()]['oAlign_' . $paragraph->getAlignment()->getLevel()] = $paragraph->getAlignment();
845 14
            }
846 14
847 14
            $richtexts  = $paragraph->getRichTextElements();
848
            $richtextId = 0;
849
            foreach ($richtexts as $richtext) {
850 14
                ++$richtextId;
851 14
                // Not a line break
852 14
                if ($richtext instanceof Run) {
853 8
                    // Style des font text
854
                    if (!isset($this->arrStyleTextFont[$richtext->getHashCode()])) {
855 8
                        $this->arrStyleTextFont[$richtext->getHashCode()] = $richtext;
856
                    }
857 8
                }
858 14
            }
859
        }
860
    }
861
862
    /**
863 14
     * Write the default style information for an AbstractDrawing
864
     *
865
     * @param \PhpOffice\Common\XMLWriter $objWriter
866
     * @param \PhpOffice\PhpPresentation\Shape\AbstractDrawing $shape
867
     */
868
    public function writeDrawingStyle(XMLWriter $objWriter, AbstractDrawing $shape)
869
    {
870
        // style:style
871 35
        $objWriter->startElement('style:style');
872
        $objWriter->writeAttribute('style:name', 'gr' . $this->shapeId);
873
        $objWriter->writeAttribute('style:family', 'graphic');
874 35
        $objWriter->writeAttribute('style:parent-style-name', 'standard');
875 35
876 35
        // style:graphic-properties
877 35
        $objWriter->startElement('style:graphic-properties');
878
        $objWriter->writeAttribute('draw:stroke', 'none');
879
        $objWriter->writeAttribute('draw:fill', 'none');
880 35
        if ($shape->getShadow()->isVisible()) {
881 35
            $this->writeStylePartShadow($objWriter, $shape->getShadow());
882 35
        }
883 35
        $objWriter->endElement();
884
885
        $objWriter->endElement();
886 35
    }
887
888 35
    /**
889 35
     * Write the default style information for a Line shape.
890
     *
891
     * @param XMLWriter $objWriter
892
     * @param Line $shape
893
     */
894
    public function writeLineStyle(XMLWriter $objWriter, Line $shape)
895
    {
896
        // style:style
897 1
        $objWriter->startElement('style:style');
898
        $objWriter->writeAttribute('style:name', 'gr' . $this->shapeId);
899
        $objWriter->writeAttribute('style:family', 'graphic');
900 1
        $objWriter->writeAttribute('style:parent-style-name', 'standard');
901 1
902 1
        // style:graphic-properties
903 1
        $objWriter->startElement('style:graphic-properties');
904
        $objWriter->writeAttribute('draw:fill', 'none');
905
        switch ($shape->getBorder()->getLineStyle()) {
906 1
            case Border::LINE_NONE:
907 1
                $objWriter->writeAttribute('draw:stroke', 'none');
908 1
                break;
909 1
            case Border::LINE_SINGLE:
910
                $objWriter->writeAttribute('draw:stroke', 'solid');
911
                break;
912 1
            default:
913 1
                $objWriter->writeAttribute('draw:stroke', 'none');
914 1
                break;
915
        }
916
        $objWriter->writeAttribute('svg:stroke-color', '#'.$shape->getBorder()->getColor()->getRGB());
917
        $objWriter->writeAttribute('svg:stroke-width', Text::numberFormat(CommonDrawing::pixelsToCentimeters((CommonDrawing::pointsToPixels($shape->getBorder()->getLineWidth()))), 3).'cm');
918
        $objWriter->endElement();
919 1
920 1
        $objWriter->endElement();
921 1
    }
922
923 1
    /**
924 1
     * Write the default style information for a Table shape
925
     *
926
     * @param XMLWriter $objWriter
927
     * @param Table $shape
928
     */
929
    public function writeTableStyle(XMLWriter $objWriter, Table $shape)
930
    {
931
        foreach ($shape->getRows() as $keyRow => $shapeRow) {
932 7
            // style:style
933
            $objWriter->startElement('style:style');
934 7
            $objWriter->writeAttribute('style:name', 'gr' . $this->shapeId.'r'.$keyRow);
935
            $objWriter->writeAttribute('style:family', 'table-row');
936 6
937 6
            // style:table-row-properties
938 6
            $objWriter->startElement('style:table-row-properties');
939
            $objWriter->writeAttribute('style:row-height', Text::numberFormat(CommonDrawing::pixelsToCentimeters(CommonDrawing::pointsToPixels($shapeRow->getHeight())), 3).'cm');
940
            $objWriter->endElement();
941 6
942 6
            $objWriter->endElement();
943 6
944
            foreach ($shapeRow->getCells() as $keyCell => $shapeCell) {
945 6
                // style:style
946
                $objWriter->startElement('style:style');
947 6
                $objWriter->writeAttribute('style:name', 'gr' . $this->shapeId.'r'.$keyRow.'c'.$keyCell);
948
                $objWriter->writeAttribute('style:family', 'table-cell');
949 6
950 6
                // style:graphic-properties
951 6
                $objWriter->startElement('style:graphic-properties');
952
                if ($shapeCell->getFill()->getFillType() == Fill::FILL_SOLID) {
953
                    $objWriter->writeAttribute('draw:fill', 'solid');
954 6
                    $objWriter->writeAttribute('draw:fill-color', '#'.$shapeCell->getFill()->getStartColor()->getRGB());
955 6
                }
956 1
                if ($shapeCell->getFill()->getFillType() == Fill::FILL_GRADIENT_LINEAR) {
957 1
                    $objWriter->writeAttribute('draw:fill', 'gradient');
958
                    $objWriter->writeAttribute('draw:fill-gradient-name', 'gradient_'.$shapeCell->getFill()->getHashCode());
959 6
                }
960 1
                $objWriter->endElement();
961 1
                // <style:graphic-properties
962
963 6
                // style:paragraph-properties
964
                $objWriter->startElement('style:paragraph-properties');
965
                if ($shapeCell->getBorders()->getBottom()->getHashCode() == $shapeCell->getBorders()->getTop()->getHashCode()
966
                    && $shapeCell->getBorders()->getBottom()->getHashCode() == $shapeCell->getBorders()->getLeft()->getHashCode()
967 6
                    && $shapeCell->getBorders()->getBottom()->getHashCode() == $shapeCell->getBorders()->getRight()->getHashCode()) {
968 6
                    $lineStyle = 'none';
969 6
                    $lineWidth = Text::numberFormat($shapeCell->getBorders()->getBottom()->getLineWidth() / 1.75, 2);
970 6
                    $lineColor = $shapeCell->getBorders()->getBottom()->getColor()->getRGB();
971 6
                    switch ($shapeCell->getBorders()->getBottom()->getLineStyle()) {
972 6
                        case Border::LINE_SINGLE:
973 6
                            $lineStyle = 'solid';
974 6
                    }
975 6
                    $objWriter->writeAttribute('fo:border', $lineWidth.'pt '.$lineStyle.' #'.$lineColor);
976 6
                } else {
977
                    $lineStyle = 'none';
978 6
                    $lineWidth = Text::numberFormat($shapeCell->getBorders()->getBottom()->getLineWidth() / 1.75, 2);
979
                    $lineColor = $shapeCell->getBorders()->getBottom()->getColor()->getRGB();
980
                    switch ($shapeCell->getBorders()->getBottom()->getLineStyle()) {
981
                        case Border::LINE_SINGLE:
982
                            $lineStyle = 'solid';
983
                    }
984
                    $objWriter->writeAttribute('fo:border-bottom', $lineWidth.'pt '.$lineStyle.' #'.$lineColor);
985
                    // TOP
986
                    $lineStyle = 'none';
987
                    $lineWidth = Text::numberFormat($shapeCell->getBorders()->getTop()->getLineWidth() / 1.75, 2);
988
                    $lineColor = $shapeCell->getBorders()->getTop()->getColor()->getRGB();
989
                    switch ($shapeCell->getBorders()->getTop()->getLineStyle()) {
990
                        case Border::LINE_SINGLE:
991
                            $lineStyle = 'solid';
992
                    }
993
                    $objWriter->writeAttribute('fo:border-top', $lineWidth.'pt '.$lineStyle.' #'.$lineColor);
994
                    // RIGHT
995
                    $lineStyle = 'none';
996
                    $lineWidth = Text::numberFormat($shapeCell->getBorders()->getRight()->getLineWidth() / 1.75, 2);
997
                    $lineColor = $shapeCell->getBorders()->getRight()->getColor()->getRGB();
998
                    switch ($shapeCell->getBorders()->getRight()->getLineStyle()) {
999
                        case Border::LINE_SINGLE:
1000
                            $lineStyle = 'solid';
1001
                    }
1002
                    $objWriter->writeAttribute('fo:border-right', $lineWidth.'pt '.$lineStyle.' #'.$lineColor);
1003
                    // LEFT
1004
                    $lineStyle = 'none';
1005
                    $lineWidth = Text::numberFormat($shapeCell->getBorders()->getLeft()->getLineWidth() / 1.75, 2);
1006
                    $lineColor = $shapeCell->getBorders()->getLeft()->getColor()->getRGB();
1007
                    switch ($shapeCell->getBorders()->getLeft()->getLineStyle()) {
1008
                        case Border::LINE_SINGLE:
1009
                            $lineStyle = 'solid';
1010
                    }
1011
                    $objWriter->writeAttribute('fo:border-left', $lineWidth.'pt '.$lineStyle.' #'.$lineColor);
1012
                }
1013
                $objWriter->endElement();
1014
1015
                $objWriter->endElement();
1016 6
1017
                foreach ($shapeCell->getParagraphs() as $shapeParagraph) {
1018 6
                    foreach ($shapeParagraph->getRichTextElements() as $shapeRichText) {
1019
                        if ($shapeRichText instanceof Run) {
1020 6
                            // Style des font text
1021 6
                            if (!isset($this->arrStyleTextFont[$shapeRichText->getHashCode()])) {
1022 2
                                $this->arrStyleTextFont[$shapeRichText->getHashCode()] = $shapeRichText;
1023
                            }
1024 2
                        }
1025 6
                    }
1026
                }
1027
            }
1028
        }
1029
    }
1030
1031
    /**
1032 7
     * Write the slide note
1033
     * @param XMLWriter $objWriter
1034
     * @param \PhpOffice\PhpPresentation\Slide\Note $note
1035
     */
1036
    public function writeSlideNote(XMLWriter $objWriter, Note $note)
1037
    {
1038
        $shapesNote = $note->getShapeCollection();
1039 57
        if (count($shapesNote) > 0) {
1040
            $objWriter->startElement('presentation:notes');
1041 57
1042 57
            foreach ($shapesNote as $shape) {
1043 1
                // Increment $this->shapeId
1044
                ++$this->shapeId;
1045 1
1046
                if ($shape instanceof RichText) {
1047 1
                    $this->writeShapeTxt($objWriter, $shape);
1048
                }
1049 1
            }
1050 1
1051
            $objWriter->endElement();
1052
        }
1053
    }
1054 1
1055
    /**
1056 57
     * Write style of a slide
1057
     * @param XMLWriter $objWriter
1058
     * @param Slide $slide
1059
     * @param int $incPage
1060
     */
1061
    public function writeStyleSlide(XMLWriter $objWriter, Slide $slide, $incPage)
1062
    {
1063
        // style:style
1064 57
        $objWriter->startElement('style:style');
1065
        $objWriter->writeAttribute('style:family', 'drawing-page');
1066
        $objWriter->writeAttribute('style:name', 'stylePage'.$incPage);
1067 57
        // style:style/style:drawing-page-properties
1068 57
        $objWriter->startElement('style:drawing-page-properties');
1069 57
        if (!is_null($oTransition = $slide->getTransition())) {
1070
            $objWriter->writeAttribute('presentation:duration', 'PT'.number_format($oTransition->getAdvanceTimeTrigger() / 1000, 6, '.', '').'S');
1071 57
            if ($oTransition->hasManualTrigger()) {
1072 57
                $objWriter->writeAttribute('presentation:transition-type', 'manual');
1073 1
            } elseif ($oTransition->hasTimeTrigger()) {
1074 1
                $objWriter->writeAttribute('presentation:transition-type', 'automatic');
1075 1
            }
1076 1
            switch ($oTransition->getSpeed()) {
1077 1
                case Transition::SPEED_FAST:
1078
                    $objWriter->writeAttribute('presentation:transition-speed', 'fast');
1079 1
                    break;
1080 1
                case Transition::SPEED_MEDIUM:
1081 1
                    $objWriter->writeAttribute('presentation:transition-speed', 'medium');
1082 1
                    break;
1083 1
                case Transition::SPEED_SLOW:
1084 1
                    $objWriter->writeAttribute('presentation:transition-speed', 'slow');
1085 1
                    break;
1086 1
            }
1087 1
1088 1
            /**
1089
             * http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os-part1.html#property-presentation_transition-style
1090
             */
1091
            switch ($oTransition->getTransitionType()) {
1092
                case Transition::TRANSITION_BLINDS_HORIZONTAL:
1093
                    $objWriter->writeAttribute('presentation:transition-style', 'horizontal-stripes');
1094 1
                    break;
1095 1
                case Transition::TRANSITION_BLINDS_VERTICAL:
1096 1
                    $objWriter->writeAttribute('presentation:transition-style', 'vertical-stripes');
1097 1
                    break;
1098 1
                case Transition::TRANSITION_CHECKER_HORIZONTAL:
1099 1
                    $objWriter->writeAttribute('presentation:transition-style', 'horizontal-checkerboard');
1100 1
                    break;
1101 1
                case Transition::TRANSITION_CHECKER_VERTICAL:
1102 1
                    $objWriter->writeAttribute('presentation:transition-style', 'vertical-checkerboard');
1103 1
                    break;
1104 1
                case Transition::TRANSITION_CIRCLE_HORIZONTAL:
1105 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1106 1
                    break;
1107 1
                case Transition::TRANSITION_CIRCLE_VERTICAL:
1108 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1109 1
                    break;
1110 1
                case Transition::TRANSITION_COMB_HORIZONTAL:
1111 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1112 1
                    break;
1113 1
                case Transition::TRANSITION_COMB_VERTICAL:
1114 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1115 1
                    break;
1116 1
                case Transition::TRANSITION_COVER_DOWN:
1117 1
                    $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-bottom');
1118 1
                    break;
1119 1
                case Transition::TRANSITION_COVER_LEFT:
1120 1
                    $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-left');
1121 1
                    break;
1122 1
                case Transition::TRANSITION_COVER_LEFT_DOWN:
1123 1
                    $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-lowerleft');
1124 1
                    break;
1125 1
                case Transition::TRANSITION_COVER_LEFT_UP:
1126 1
                    $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-upperleft');
1127 1
                    break;
1128 1
                case Transition::TRANSITION_COVER_RIGHT:
1129 1
                    $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-right');
1130 1
                    break;
1131 1
                case Transition::TRANSITION_COVER_RIGHT_DOWN:
1132 1
                    $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-lowerright');
1133 1
                    break;
1134 1
                case Transition::TRANSITION_COVER_RIGHT_UP:
1135 1
                    $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-upperright');
1136 1
                    break;
1137 1
                case Transition::TRANSITION_COVER_UP:
1138 1
                    $objWriter->writeAttribute('presentation:transition-style', 'uncover-to-top');
1139 1
                    break;
1140 1
                case Transition::TRANSITION_CUT:
1141 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1142 1
                    break;
1143 1
                case Transition::TRANSITION_DIAMOND:
1144 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1145 1
                    break;
1146 1
                case Transition::TRANSITION_DISSOLVE:
1147 1
                    $objWriter->writeAttribute('presentation:transition-style', 'dissolve');
1148 1
                    break;
1149 1
                case Transition::TRANSITION_FADE:
1150 1
                    $objWriter->writeAttribute('presentation:transition-style', 'fade-from-center');
1151 1
                    break;
1152 1
                case Transition::TRANSITION_NEWSFLASH:
1153 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1154 1
                    break;
1155 1
                case Transition::TRANSITION_PLUS:
1156 1
                    $objWriter->writeAttribute('presentation:transition-style', 'close');
1157 1
                    break;
1158 1
                case Transition::TRANSITION_PULL_DOWN:
1159 1
                    $objWriter->writeAttribute('presentation:transition-style', 'stretch-from-bottom');
1160 1
                    break;
1161 1
                case Transition::TRANSITION_PULL_LEFT:
1162 1
                    $objWriter->writeAttribute('presentation:transition-style', 'stretch-from-left');
1163 1
                    break;
1164 1
                case Transition::TRANSITION_PULL_RIGHT:
1165 1
                    $objWriter->writeAttribute('presentation:transition-style', 'stretch-from-right');
1166 1
                    break;
1167 1
                case Transition::TRANSITION_PULL_UP:
1168 1
                    $objWriter->writeAttribute('presentation:transition-style', 'stretch-from-top');
1169 1
                    break;
1170 1
                case Transition::TRANSITION_PUSH_DOWN:
1171 1
                    $objWriter->writeAttribute('presentation:transition-style', 'roll-from-bottom');
1172 1
                    break;
1173 1
                case Transition::TRANSITION_PUSH_LEFT:
1174 1
                    $objWriter->writeAttribute('presentation:transition-style', 'roll-from-left');
1175 1
                    break;
1176 1
                case Transition::TRANSITION_PUSH_RIGHT:
1177 1
                    $objWriter->writeAttribute('presentation:transition-style', 'roll-from-right');
1178 1
                    break;
1179 1
                case Transition::TRANSITION_PUSH_UP:
1180 1
                    $objWriter->writeAttribute('presentation:transition-style', 'roll-from-top');
1181 1
                    break;
1182 1
                case Transition::TRANSITION_RANDOM:
1183 1
                    $objWriter->writeAttribute('presentation:transition-style', 'random');
1184 1
                    break;
1185 1
                case Transition::TRANSITION_RANDOMBAR_HORIZONTAL:
1186 1
                    $objWriter->writeAttribute('presentation:transition-style', 'horizontal-lines');
1187 1
                    break;
1188 1
                case Transition::TRANSITION_RANDOMBAR_VERTICAL:
1189 1
                    $objWriter->writeAttribute('presentation:transition-style', 'vertical-lines');
1190 1
                    break;
1191 1
                case Transition::TRANSITION_SPLIT_IN_HORIZONTAL:
1192 1
                    $objWriter->writeAttribute('presentation:transition-style', 'close-horizontal');
1193 1
                    break;
1194 1
                case Transition::TRANSITION_SPLIT_OUT_HORIZONTAL:
1195 1
                    $objWriter->writeAttribute('presentation:transition-style', 'open-horizontal');
1196 1
                    break;
1197 1
                case Transition::TRANSITION_SPLIT_IN_VERTICAL:
1198 1
                    $objWriter->writeAttribute('presentation:transition-style', 'close-vertical');
1199 1
                    break;
1200 1
                case Transition::TRANSITION_SPLIT_OUT_VERTICAL:
1201 1
                    $objWriter->writeAttribute('presentation:transition-style', 'open-vertical');
1202 1
                    break;
1203 1
                case Transition::TRANSITION_STRIPS_LEFT_DOWN:
1204 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1205 1
                    break;
1206 1
                case Transition::TRANSITION_STRIPS_LEFT_UP:
1207 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1208 1
                    break;
1209 1
                case Transition::TRANSITION_STRIPS_RIGHT_DOWN:
1210 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1211 1
                    break;
1212 1
                case Transition::TRANSITION_STRIPS_RIGHT_UP:
1213 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1214 1
                    break;
1215 1
                case Transition::TRANSITION_WEDGE:
1216 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1217 1
                    break;
1218 1
                case Transition::TRANSITION_WIPE_DOWN:
1219 1
                    $objWriter->writeAttribute('presentation:transition-style', 'fade-from-bottom');
1220 1
                    break;
1221 1
                case Transition::TRANSITION_WIPE_LEFT:
1222 1
                    $objWriter->writeAttribute('presentation:transition-style', 'fade-from-left');
1223 1
                    break;
1224 1
                case Transition::TRANSITION_WIPE_RIGHT:
1225 1
                    $objWriter->writeAttribute('presentation:transition-style', 'fade-from-right');
1226 1
                    break;
1227 1
                case Transition::TRANSITION_WIPE_UP:
1228 1
                    $objWriter->writeAttribute('presentation:transition-style', 'fade-from-top');
1229 1
                    break;
1230 1
                case Transition::TRANSITION_ZOOM_IN:
1231 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1232 1
                    break;
1233 1
                case Transition::TRANSITION_ZOOM_OUT:
1234 1
                    $objWriter->writeAttribute('presentation:transition-style', 'none');
1235 1
                    break;
1236 1
            }
1237 1
        }
1238 1
        $oBackground = $slide->getBackground();
1239
        if ($oBackground instanceof Slide\AbstractBackground) {
1240
            $objWriter->writeAttribute('presentation:background-visible', 'true');
1241 57
            if ($oBackground instanceof Slide\Background\Color) {
1242 57
                $objWriter->writeAttribute('draw:fill', 'solid');
1243 1
                $objWriter->writeAttribute('draw:fill-color', '#' . $oBackground->getColor()->getRGB());
1244 1
            }
1245
            if ($oBackground instanceof Slide\Background\Image) {
1246
                $objWriter->writeAttribute('draw:fill', 'bitmap');
1247
                $objWriter->writeAttribute('draw:fill-image-name', 'background_'.$incPage);
1248 1
                $objWriter->writeAttribute('style:repeat', 'stretch');
1249 1
            }
1250 1
        }
1251 1
        $objWriter->endElement();
1252
        // > style:style
1253
        $objWriter->endElement();
1254 57
    }
1255
1256 57
1257 57
    /**
1258
     * @param XMLWriter $objWriter
1259
     * @param Shadow $oShadow
1260
     * @todo Improve for supporting any direction (https://sinepost.wordpress.com/2012/02/16/theyve-got-atan-you-want-atan2/)
1261
     */
1262
    protected function writeStylePartShadow(XMLWriter $objWriter, Shadow $oShadow)
1263
    {
1264
        $objWriter->writeAttribute('draw:shadow', 'visible');
1265 1
        $objWriter->writeAttribute('draw:shadow-color', '#' . $oShadow->getColor()->getRGB());
1266
        if ($oShadow->getDirection() == 0 || $oShadow->getDirection() == 360) {
1267 1
            $objWriter->writeAttribute('draw:shadow-offset-x', CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm');
1268 1
            $objWriter->writeAttribute('draw:shadow-offset-y', '0cm');
1269 1
        } elseif ($oShadow->getDirection() == 45) {
1270 1
            $objWriter->writeAttribute('draw:shadow-offset-x', CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm');
1271 1
            $objWriter->writeAttribute('draw:shadow-offset-y', CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm');
1272 1
        } elseif ($oShadow->getDirection() == 90) {
1273 1
            $objWriter->writeAttribute('draw:shadow-offset-x', '0cm');
1274 1
            $objWriter->writeAttribute('draw:shadow-offset-y', CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm');
1275 1
        } elseif ($oShadow->getDirection() == 135) {
1276 1
            $objWriter->writeAttribute('draw:shadow-offset-x', '-' . CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm');
1277 1
            $objWriter->writeAttribute('draw:shadow-offset-y', CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm');
1278 1
        } elseif ($oShadow->getDirection() == 180) {
1279 1
            $objWriter->writeAttribute('draw:shadow-offset-x', '-' . CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm');
1280 1
            $objWriter->writeAttribute('draw:shadow-offset-y', '0cm');
1281 1
        } elseif ($oShadow->getDirection() == 225) {
1282 1
            $objWriter->writeAttribute('draw:shadow-offset-x', '-' . CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm');
1283 1
            $objWriter->writeAttribute('draw:shadow-offset-y', '-' . CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm');
1284 1
        } elseif ($oShadow->getDirection() == 270) {
1285 1
            $objWriter->writeAttribute('draw:shadow-offset-x', '0cm');
1286 1
            $objWriter->writeAttribute('draw:shadow-offset-y', '-' . CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm');
1287 1
        } elseif ($oShadow->getDirection() == 315) {
1288 1
            $objWriter->writeAttribute('draw:shadow-offset-x', CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm');
1289 1
            $objWriter->writeAttribute('draw:shadow-offset-y', '-' . CommonDrawing::pixelsToCentimeters($oShadow->getDistance()) . 'cm');
1290 1
        }
1291 1
        $objWriter->writeAttribute('draw:shadow-opacity', (100 - $oShadow->getAlpha()) . '%');
1292 1
        $objWriter->writeAttribute('style:mirror', 'none');
1293
1294 1
    }
1295
}
1296