Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
84.40% covered (warning)
84.40%
92 / 109
66.67% covered (warning)
66.67%
6 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
AbstractDecoratorWriter
84.40% covered (warning)
84.40%
92 / 109
66.67% covered (warning)
66.67%
6 / 9
28.56
0.00% covered (danger)
0.00%
0 / 1
 writeRelationship
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 writeBorder
96.97% covered (success)
96.97%
32 / 33
0.00% covered (danger)
0.00%
0 / 1
7
 writeColor
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
2
 writeFill
91.67% covered (success)
91.67%
11 / 12
0.00% covered (danger)
0.00%
0 / 1
6.02
 writeSolidFill
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 writeGradientFill
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
1
 writePatternFill
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 writeOutline
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 absoluteZipPath
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
20
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 * @see        https://github.com/PHPOffice/PHPPresentation
14 *
15 * @license     http://www.gnu.org/licenses/lgpl.txt LGPL version 3
16 */
17
18declare(strict_types=1);
19
20namespace PhpOffice\PhpPresentation\Writer\PowerPoint2007;
21
22use PhpOffice\Common\Drawing as CommonDrawing;
23use PhpOffice\Common\XMLWriter;
24use PhpOffice\PhpPresentation\Style\Border;
25use PhpOffice\PhpPresentation\Style\Color;
26use PhpOffice\PhpPresentation\Style\Fill;
27use PhpOffice\PhpPresentation\Style\Outline;
28
29abstract class AbstractDecoratorWriter extends \PhpOffice\PhpPresentation\Writer\AbstractDecoratorWriter
30{
31    /**
32     * Write relationship.
33     *
34     * @param XMLWriter $objWriter XML Writer
35     * @param int $pId Relationship ID. rId will be prepended!
36     * @param string $pType Relationship type
37     * @param string $pTarget Relationship target
38     * @param string $pTargetMode Relationship target mode
39     */
40    protected function writeRelationship(XMLWriter $objWriter, int $pId, string $pType, string $pTarget, string $pTargetMode = ''): void
41    {
42        // Write relationship
43        $objWriter->startElement('Relationship');
44        $objWriter->writeAttribute('Id', 'rId' . (string) $pId);
45        $objWriter->writeAttribute('Type', $pType);
46        $objWriter->writeAttribute('Target', $pTarget);
47
48        if ('' != $pTargetMode) {
49            $objWriter->writeAttribute('TargetMode', $pTargetMode);
50        }
51
52        $objWriter->endElement();
53    }
54
55    /**
56     * Write Border.
57     *
58     * @param XMLWriter $objWriter XML Writer
59     * @param Border $pBorder Border
60     * @param string $pElementName Element name
61     */
62    protected function writeBorder(XMLWriter $objWriter, Border $pBorder, string $pElementName = 'L', bool $isMarker = false): void
63    {
64        if (!($pBorder instanceof Border)) {
65            return;
66        }
67
68        if (Border::LINE_NONE == $pBorder->getLineStyle() && '' == $pElementName && !$isMarker) {
69            return;
70        }
71
72        // Line style
73        $lineStyle = $pBorder->getLineStyle();
74        if (Border::LINE_NONE == $lineStyle) {
75            $lineStyle = Border::LINE_SINGLE;
76        }
77
78        // Line width
79        $lineWidth = 12700 * $pBorder->getLineWidth();
80
81        // a:ln $pElementName
82        $objWriter->startElement('a:ln' . $pElementName);
83        $objWriter->writeAttribute('w', $lineWidth);
84        $objWriter->writeAttribute('cap', 'flat');
85        $objWriter->writeAttribute('cmpd', $lineStyle);
86        $objWriter->writeAttribute('algn', 'ctr');
87
88        // Fill?
89        if (Border::LINE_NONE == $pBorder->getLineStyle()) {
90            // a:noFill
91            $objWriter->writeElement('a:noFill', null);
92        } else {
93            // a:solidFill
94            $objWriter->startElement('a:solidFill');
95            $this->writeColor($objWriter, $pBorder->getColor());
96            $objWriter->endElement();
97        }
98
99        // Dash
100        $objWriter->startElement('a:prstDash');
101        $objWriter->writeAttribute('val', $pBorder->getDashStyle());
102        $objWriter->endElement();
103
104        // a:round
105        $objWriter->writeElement('a:round', null);
106
107        // a:headEnd
108        $objWriter->startElement('a:headEnd');
109        $objWriter->writeAttribute('type', 'none');
110        $objWriter->writeAttribute('w', 'med');
111        $objWriter->writeAttribute('len', 'med');
112        $objWriter->endElement();
113
114        // a:tailEnd
115        $objWriter->startElement('a:tailEnd');
116        $objWriter->writeAttribute('type', 'none');
117        $objWriter->writeAttribute('w', 'med');
118        $objWriter->writeAttribute('len', 'med');
119        $objWriter->endElement();
120
121        $objWriter->endElement();
122    }
123
124    protected function writeColor(XMLWriter $objWriter, Color $color, ?int $alpha = null): void
125    {
126        if (null === $alpha) {
127            $alpha = $color->getAlpha();
128        }
129
130        // a:srgbClr
131        $objWriter->startElement('a:srgbClr');
132        $objWriter->writeAttribute('val', $color->getRGB());
133
134        // a:alpha
135        $objWriter->startElement('a:alpha');
136        $objWriter->writeAttribute('val', $alpha * 1000);
137        $objWriter->endElement();
138
139        $objWriter->endElement();
140    }
141
142    /**
143     * Write Fill.
144     *
145     * @param XMLWriter $objWriter XML Writer
146     * @param null|Fill $pFill Fill style
147     */
148    protected function writeFill(XMLWriter $objWriter, ?Fill $pFill): void
149    {
150        if (!$pFill) {
151            return;
152        }
153
154        // Is it a fill?
155        if (Fill::FILL_NONE == $pFill->getFillType()) {
156            $objWriter->writeElement('a:noFill');
157
158            return;
159        }
160
161        // Is it a solid fill?
162        if (Fill::FILL_SOLID == $pFill->getFillType()) {
163            $this->writeSolidFill($objWriter, $pFill);
164
165            return;
166        }
167
168        // Is it a gradient fill?
169        if (Fill::FILL_GRADIENT_LINEAR == $pFill->getFillType() || Fill::FILL_GRADIENT_PATH == $pFill->getFillType()) {
170            $this->writeGradientFill($objWriter, $pFill);
171
172            return;
173        }
174
175        // Is it a pattern fill?
176        $this->writePatternFill($objWriter, $pFill);
177    }
178
179    /**
180     * Write Solid Fill.
181     *
182     * @param XMLWriter $objWriter XML Writer
183     * @param Fill $pFill Fill style
184     */
185    protected function writeSolidFill(XMLWriter $objWriter, Fill $pFill): void
186    {
187        // a:gradFill
188        $objWriter->startElement('a:solidFill');
189        $this->writeColor($objWriter, $pFill->getStartColor());
190        $objWriter->endElement();
191    }
192
193    /**
194     * Write Gradient Fill.
195     *
196     * @param XMLWriter $objWriter XML Writer
197     * @param Fill $pFill Fill style
198     */
199    protected function writeGradientFill(XMLWriter $objWriter, Fill $pFill): void
200    {
201        // a:gradFill
202        $objWriter->startElement('a:gradFill');
203
204        // a:gsLst
205        $objWriter->startElement('a:gsLst');
206        // a:gs
207        $objWriter->startElement('a:gs');
208        $objWriter->writeAttribute('pos', '0');
209        $this->writeColor($objWriter, $pFill->getStartColor());
210        $objWriter->endElement();
211
212        // a:gs
213        $objWriter->startElement('a:gs');
214        $objWriter->writeAttribute('pos', '100000');
215        $this->writeColor($objWriter, $pFill->getEndColor());
216        $objWriter->endElement();
217
218        $objWriter->endElement();
219
220        // a:lin
221        $objWriter->startElement('a:lin');
222        $objWriter->writeAttribute('ang', CommonDrawing::degreesToAngle((int) $pFill->getRotation()));
223        $objWriter->writeAttribute('scaled', '0');
224        $objWriter->endElement();
225
226        $objWriter->endElement();
227    }
228
229    /**
230     * Write Pattern Fill.
231     *
232     * @param XMLWriter $objWriter XML Writer
233     * @param Fill $pFill Fill style
234     */
235    protected function writePatternFill(XMLWriter $objWriter, Fill $pFill): void
236    {
237        // a:pattFill
238        $objWriter->startElement('a:pattFill');
239
240        // fgClr
241        $objWriter->startElement('a:fgClr');
242
243        $this->writeColor($objWriter, $pFill->getStartColor());
244
245        $objWriter->endElement();
246
247        // bgClr
248        $objWriter->startElement('a:bgClr');
249
250        $this->writeColor($objWriter, $pFill->getEndColor());
251
252        $objWriter->endElement();
253
254        $objWriter->endElement();
255    }
256
257    /**
258     * Write Outline.
259     */
260    protected function writeOutline(XMLWriter $objWriter, ?Outline $oOutline): void
261    {
262        if (!$oOutline) {
263            return;
264        }
265        // Width : pts
266        $width = CommonDrawing::pixelsToEmu($oOutline->getWidth());
267
268        // a:ln
269        $objWriter->startElement('a:ln');
270        $objWriter->writeAttribute('w', $width);
271
272        // Fill
273        $this->writeFill($objWriter, $oOutline->getFill());
274
275        // > a:ln
276        $objWriter->endElement();
277    }
278
279    /**
280     * Determine absolute zip path.
281     */
282    protected function absoluteZipPath(string $path): string
283    {
284        $path = str_replace([
285            '/',
286            '\\',
287        ], DIRECTORY_SEPARATOR, $path);
288        $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), function (string $var) {
289            return (bool) strlen($var);
290        });
291        $absolutes = [];
292        foreach ($parts as $part) {
293            if ('.' == $part) {
294                continue;
295            }
296            if ('..' == $part) {
297                array_pop($absolutes);
298            } else {
299                $absolutes[] = $part;
300            }
301        }
302
303        return implode('/', $absolutes);
304    }
305}