Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
44 / 44
100.00% covered (success)
100.00%
8 / 8
CRAP
100.00% covered (success)
100.00%
1 / 1
DocumentLayout
100.00% covered (success)
100.00%
44 / 44
100.00% covered (success)
100.00%
8 / 8
36
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDocumentLayout
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setDocumentLayout
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
15
 getCX
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCY
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setCX
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 setCY
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 convertUnit
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
15
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;
21
22use PhpOffice\Common\Drawing;
23
24/**
25 * \PhpOffice\PhpPresentation\DocumentLayout.
26 */
27class DocumentLayout
28{
29    public const LAYOUT_CUSTOM = '';
30    public const LAYOUT_SCREEN_4X3 = 'screen4x3';
31    public const LAYOUT_SCREEN_16X10 = 'screen16x10';
32    public const LAYOUT_SCREEN_16X9 = 'screen16x9';
33    public const LAYOUT_35MM = '35mm';
34    public const LAYOUT_A3 = 'A3';
35    public const LAYOUT_A4 = 'A4';
36    public const LAYOUT_B4ISO = 'B4ISO';
37    public const LAYOUT_B5ISO = 'B5ISO';
38    public const LAYOUT_BANNER = 'banner';
39    public const LAYOUT_LETTER = 'letter';
40    public const LAYOUT_OVERHEAD = 'overhead';
41
42    public const UNIT_EMU = 'emu';
43    public const UNIT_CENTIMETER = 'cm';
44    public const UNIT_INCH = 'in';
45    public const UNIT_MILLIMETER = 'mm';
46    public const UNIT_PIXEL = 'px';
47    public const UNIT_POINT = 'pt';
48
49    /**
50     * Dimension types.
51     *
52     * 1 px = 9525 EMU @ 96dpi (which is seems to be the default)
53     * Absolute distances are specified in English Metric Units (EMUs),
54     * occasionally referred to as A units; there are 360000 EMUs per
55     * centimeter, 914400 EMUs per inch, 12700 EMUs per point.
56     *
57     * @var array<string, array<string, int>>
58     */
59    private $dimension = [
60        self::LAYOUT_SCREEN_4X3 => ['cx' => 9144000, 'cy' => 6858000],
61        self::LAYOUT_SCREEN_16X10 => ['cx' => 9144000, 'cy' => 5715000],
62        self::LAYOUT_SCREEN_16X9 => ['cx' => 9144000, 'cy' => 5143500],
63        self::LAYOUT_35MM => ['cx' => 10287000, 'cy' => 6858000],
64        self::LAYOUT_A3 => ['cx' => 15120000, 'cy' => 10692000],
65        self::LAYOUT_A4 => ['cx' => 10692000, 'cy' => 7560000],
66        self::LAYOUT_B4ISO => ['cx' => 10826750, 'cy' => 8120063],
67        self::LAYOUT_B5ISO => ['cx' => 7169150, 'cy' => 5376863],
68        self::LAYOUT_BANNER => ['cx' => 7315200, 'cy' => 914400],
69        self::LAYOUT_LETTER => ['cx' => 9144000, 'cy' => 6858000],
70        self::LAYOUT_OVERHEAD => ['cx' => 9144000, 'cy' => 6858000],
71    ];
72
73    /**
74     * Layout name.
75     *
76     * @var string
77     */
78    private $layout;
79
80    /**
81     * Layout X dimension.
82     *
83     * @var float
84     */
85    private $dimensionX;
86
87    /**
88     * Layout Y dimension.
89     *
90     * @var float
91     */
92    private $dimensionY;
93
94    /**
95     * Create a new \PhpOffice\PhpPresentation\DocumentLayout.
96     */
97    public function __construct()
98    {
99        $this->setDocumentLayout(self::LAYOUT_SCREEN_4X3);
100    }
101
102    /**
103     * Get Document Layout.
104     */
105    public function getDocumentLayout(): string
106    {
107        return $this->layout;
108    }
109
110    /**
111     * Set Document Layout.
112     *
113     * @param array<string, int>|string $pValue
114     * @param bool $isLandscape
115     */
116    public function setDocumentLayout($pValue = self::LAYOUT_SCREEN_4X3, $isLandscape = true): self
117    {
118        switch ($pValue) {
119            case self::LAYOUT_SCREEN_4X3:
120            case self::LAYOUT_SCREEN_16X10:
121            case self::LAYOUT_SCREEN_16X9:
122            case self::LAYOUT_35MM:
123            case self::LAYOUT_A3:
124            case self::LAYOUT_A4:
125            case self::LAYOUT_B4ISO:
126            case self::LAYOUT_B5ISO:
127            case self::LAYOUT_BANNER:
128            case self::LAYOUT_LETTER:
129            case self::LAYOUT_OVERHEAD:
130                $this->layout = $pValue;
131                $this->dimensionX = $this->dimension[$this->layout]['cx'];
132                $this->dimensionY = $this->dimension[$this->layout]['cy'];
133
134                break;
135            case self::LAYOUT_CUSTOM:
136            default:
137                $this->layout = self::LAYOUT_CUSTOM;
138                $this->dimensionX = $pValue['cx'];
139                $this->dimensionY = $pValue['cy'];
140
141                break;
142        }
143
144        if (!$isLandscape) {
145            $tmp = $this->dimensionX;
146            $this->dimensionX = $this->dimensionY;
147            $this->dimensionY = $tmp;
148        }
149
150        return $this;
151    }
152
153    /**
154     * Get Document Layout cx.
155     */
156    public function getCX(string $unit = self::UNIT_EMU): float
157    {
158        return $this->convertUnit($this->dimensionX, self::UNIT_EMU, $unit);
159    }
160
161    /**
162     * Get Document Layout cy.
163     */
164    public function getCY(string $unit = self::UNIT_EMU): float
165    {
166        return $this->convertUnit($this->dimensionY, self::UNIT_EMU, $unit);
167    }
168
169    /**
170     * Get Document Layout cx.
171     */
172    public function setCX(float $value, string $unit = self::UNIT_EMU): self
173    {
174        $this->layout = self::LAYOUT_CUSTOM;
175        $this->dimensionX = $this->convertUnit($value, $unit, self::UNIT_EMU);
176
177        return $this;
178    }
179
180    /**
181     * Get Document Layout cy.
182     */
183    public function setCY(float $value, string $unit = self::UNIT_EMU): self
184    {
185        $this->layout = self::LAYOUT_CUSTOM;
186        $this->dimensionY = $this->convertUnit($value, $unit, self::UNIT_EMU);
187
188        return $this;
189    }
190
191    /**
192     * Convert EMUs to differents units.
193     */
194    protected function convertUnit(float $value, string $fromUnit, string $toUnit): float
195    {
196        // Convert from $fromUnit to EMU
197        switch ($fromUnit) {
198            case self::UNIT_MILLIMETER:
199                $value *= 36000;
200
201                break;
202            case self::UNIT_CENTIMETER:
203                $value *= 360000;
204
205                break;
206            case self::UNIT_INCH:
207                $value *= 914400;
208
209                break;
210            case self::UNIT_PIXEL:
211                $value = Drawing::pixelsToEmu($value);
212
213                break;
214            case self::UNIT_POINT:
215                $value *= 12700;
216
217                break;
218            case self::UNIT_EMU:
219            default:
220                // no changes
221        }
222
223        // Convert from EMU to $toUnit
224        switch ($toUnit) {
225            case self::UNIT_MILLIMETER:
226                $value /= 36000;
227
228                break;
229            case self::UNIT_CENTIMETER:
230                $value /= 360000;
231
232                break;
233            case self::UNIT_INCH:
234                $value /= 914400;
235
236                break;
237            case self::UNIT_PIXEL:
238                $value = Drawing::emuToPixels((int) $value);
239
240                break;
241            case self::UNIT_POINT:
242                $value /= 12700;
243
244                break;
245            case self::UNIT_EMU:
246            default:
247                // no changes
248        }
249
250        return $value;
251    }
252}