Failed Conditions
Push — master ( 4b6ad7...9fab89 )
by Adrien
06:57
created

Xf::setDiagColor()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Writer\Xls;
4
5
use PhpOffice\PhpSpreadsheet\Style\Alignment;
6
use PhpOffice\PhpSpreadsheet\Style\Border;
7
use PhpOffice\PhpSpreadsheet\Style\Borders;
8
use PhpOffice\PhpSpreadsheet\Style\Fill;
9
use PhpOffice\PhpSpreadsheet\Style\Protection;
10
use PhpOffice\PhpSpreadsheet\Style\Style;
11
12
// Original file header of PEAR::Spreadsheet_Excel_Writer_Format (used as the base for this class):
13
// -----------------------------------------------------------------------------------------
14
// /*
15
// *  Module written/ported by Xavier Noguer <[email protected]>
16
// *
17
// *  The majority of this is _NOT_ my code.  I simply ported it from the
18
// *  PERL Spreadsheet::WriteExcel module.
19
// *
20
// *  The author of the Spreadsheet::WriteExcel module is John McNamara
21
// *  <[email protected]>
22
// *
23
// *  I _DO_ maintain this code, and John McNamara has nothing to do with the
24
// *  porting of this code to PHP.  Any questions directly related to this
25
// *  class library should be directed to me.
26
// *
27
// *  License Information:
28
// *
29
// *    Spreadsheet_Excel_Writer:  A library for generating Excel Spreadsheets
30
// *    Copyright (c) 2002-2003 Xavier Noguer [email protected]
31
// *
32
// *    This library is free software; you can redistribute it and/or
33
// *    modify it under the terms of the GNU Lesser General Public
34
// *    License as published by the Free Software Foundation; either
35
// *    version 2.1 of the License, or (at your option) any later version.
36
// *
37
// *    This library is distributed in the hope that it will be useful,
38
// *    but WITHOUT ANY WARRANTY; without even the implied warranty of
39
// *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
40
// *    Lesser General Public License for more details.
41
// *
42
// *    You should have received a copy of the GNU Lesser General Public
43
// *    License along with this library; if not, write to the Free Software
44
// *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
45
// */
46
class Xf
47
{
48
    /**
49
     * Style XF or a cell XF ?
50
     *
51
     * @var bool
52
     */
53
    private $isStyleXf;
54
55
    /**
56
     * Index to the FONT record. Index 4 does not exist.
57
     *
58
     * @var int
59
     */
60
    private $fontIndex;
61
62
    /**
63
     * An index (2 bytes) to a FORMAT record (number format).
64
     *
65
     * @var int
66
     */
67
    private $numberFormatIndex;
68
69
    /**
70
     * 1 bit, apparently not used.
71
     *
72
     * @var int
73
     */
74
    private $textJustLast;
75
76
    /**
77
     * The cell's foreground color.
78
     *
79
     * @var int
80
     */
81
    private $foregroundColor;
82
83
    /**
84
     * The cell's background color.
85
     *
86
     * @var int
87
     */
88
    private $backgroundColor;
89
90
    /**
91
     * Color of the bottom border of the cell.
92
     *
93
     * @var int
94
     */
95
    private $bottomBorderColor;
96
97
    /**
98
     * Color of the top border of the cell.
99
     *
100
     * @var int
101
     */
102
    private $topBorderColor;
103
104
    /**
105
     * Color of the left border of the cell.
106
     *
107
     * @var int
108
     */
109
    private $leftBorderColor;
110
111
    /**
112
     * Color of the right border of the cell.
113
     *
114
     * @var int
115
     */
116
    private $rightBorderColor;
117
118
    /**
119
     * Constructor.
120
     *
121
     * @param Style $style The XF format
122
     */
123 44
    public function __construct(Style $style)
124
    {
125 44
        $this->isStyleXf = false;
126 44
        $this->fontIndex = 0;
127
128 44
        $this->numberFormatIndex = 0;
129
130 44
        $this->textJustLast = 0;
131
132 44
        $this->foregroundColor = 0x40;
133 44
        $this->backgroundColor = 0x41;
134
135 44
        $this->_diag = 0;
0 ignored issues
show
Bug Best Practice introduced by
The property _diag does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
136
137 44
        $this->bottomBorderColor = 0x40;
138 44
        $this->topBorderColor = 0x40;
139 44
        $this->leftBorderColor = 0x40;
140 44
        $this->rightBorderColor = 0x40;
141 44
        $this->_diag_color = 0x40;
0 ignored issues
show
Bug Best Practice introduced by
The property _diag_color does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
142 44
        $this->_style = $style;
0 ignored issues
show
Bug Best Practice introduced by
The property _style does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
143 44
    }
144
145
    /**
146
     * Generate an Excel BIFF XF record (style or cell).
147
     *
148
     * @return string The XF record
149
     */
150 44
    public function writeXf()
151
    {
152
        // Set the type of the XF record and some of the attributes.
153 44
        if ($this->isStyleXf) {
154 44
            $style = 0xFFF5;
155
        } else {
156 44
            $style = self::mapLocked($this->_style->getProtection()->getLocked());
157 44
            $style |= self::mapHidden($this->_style->getProtection()->getHidden()) << 1;
158
        }
159
160
        // Flags to indicate if attributes have been set.
161 44
        $atr_num = ($this->numberFormatIndex != 0) ? 1 : 0;
162 44
        $atr_fnt = ($this->fontIndex != 0) ? 1 : 0;
163 44
        $atr_alc = ((int) $this->_style->getAlignment()->getWrapText()) ? 1 : 0;
164 44
        $atr_bdr = (self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) ||
165 44
                        self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) ||
166 44
                        self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) ||
167 44
                        self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle())) ? 1 : 0;
168 44
        $atr_pat = (($this->foregroundColor != 0x40) ||
169 44
                        ($this->backgroundColor != 0x41) ||
170 44
                        self::mapFillType($this->_style->getFill()->getFillType())) ? 1 : 0;
171 44
        $atr_prot = self::mapLocked($this->_style->getProtection()->getLocked())
172 44
                        | self::mapHidden($this->_style->getProtection()->getHidden());
173
174
        // Zero the default border colour if the border has not been set.
175 44
        if (self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) == 0) {
176 44
            $this->bottomBorderColor = 0;
177
        }
178 44
        if (self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) == 0) {
179 44
            $this->topBorderColor = 0;
180
        }
181 44
        if (self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) == 0) {
182 44
            $this->rightBorderColor = 0;
183
        }
184 44
        if (self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) == 0) {
185 44
            $this->leftBorderColor = 0;
186
        }
187 44
        if (self::mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) == 0) {
188 44
            $this->_diag_color = 0;
0 ignored issues
show
Bug Best Practice introduced by
The property _diag_color does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
189
        }
190
191 44
        $record = 0x00E0; // Record identifier
192 44
        $length = 0x0014; // Number of bytes to follow
193
194 44
        $ifnt = $this->fontIndex; // Index to FONT record
195 44
        $ifmt = $this->numberFormatIndex; // Index to FORMAT record
196
197 44
        $align = $this->mapHAlign($this->_style->getAlignment()->getHorizontal()); // Alignment
198 44
        $align |= (int) $this->_style->getAlignment()->getWrapText() << 3;
199 44
        $align |= self::mapVAlign($this->_style->getAlignment()->getVertical()) << 4;
200 44
        $align |= $this->textJustLast << 7;
201
202 44
        $used_attrib = $atr_num << 2;
203 44
        $used_attrib |= $atr_fnt << 3;
204 44
        $used_attrib |= $atr_alc << 4;
205 44
        $used_attrib |= $atr_bdr << 5;
206 44
        $used_attrib |= $atr_pat << 6;
207 44
        $used_attrib |= $atr_prot << 7;
208
209 44
        $icv = $this->foregroundColor; // fg and bg pattern colors
210 44
        $icv |= $this->backgroundColor << 7;
211
212 44
        $border1 = self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()); // Border line style and color
213 44
        $border1 |= self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) << 4;
214 44
        $border1 |= self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) << 8;
215 44
        $border1 |= self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) << 12;
216 44
        $border1 |= $this->leftBorderColor << 16;
217 44
        $border1 |= $this->rightBorderColor << 23;
218
219 44
        $diagonalDirection = $this->_style->getBorders()->getDiagonalDirection();
220 44
        $diag_tl_to_rb = $diagonalDirection == Borders::DIAGONAL_BOTH
221 44
                            || $diagonalDirection == Borders::DIAGONAL_DOWN;
222 44
        $diag_tr_to_lb = $diagonalDirection == Borders::DIAGONAL_BOTH
223 44
                            || $diagonalDirection == Borders::DIAGONAL_UP;
224 44
        $border1 |= $diag_tl_to_rb << 30;
225 44
        $border1 |= $diag_tr_to_lb << 31;
226
227 44
        $border2 = $this->topBorderColor; // Border color
228 44
        $border2 |= $this->bottomBorderColor << 7;
229 44
        $border2 |= $this->_diag_color << 14;
230 44
        $border2 |= self::mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) << 21;
231 44
        $border2 |= self::mapFillType($this->_style->getFill()->getFillType()) << 26;
232
233 44
        $header = pack('vv', $record, $length);
234
235
        //BIFF8 options: identation, shrinkToFit and  text direction
236 44
        $biff8_options = $this->_style->getAlignment()->getIndent();
237 44
        $biff8_options |= (int) $this->_style->getAlignment()->getShrinkToFit() << 4;
238
239 44
        $data = pack('vvvC', $ifnt, $ifmt, $style, $align);
240 44
        $data .= pack('CCC', self::mapTextRotation($this->_style->getAlignment()->getTextRotation()), $biff8_options, $used_attrib);
241 44
        $data .= pack('VVv', $border1, $border2, $icv);
242
243 44
        return $header . $data;
244
    }
245
246
    /**
247
     * Is this a style XF ?
248
     *
249
     * @param bool $value
250
     */
251 44
    public function setIsStyleXf($value)
252
    {
253 44
        $this->isStyleXf = $value;
254 44
    }
255
256
    /**
257
     * Sets the cell's bottom border color.
258
     *
259
     * @param int $colorIndex Color index
260
     */
261 44
    public function setBottomColor($colorIndex)
262
    {
263 44
        $this->bottomBorderColor = $colorIndex;
264 44
    }
265
266
    /**
267
     * Sets the cell's top border color.
268
     *
269
     * @param int $colorIndex Color index
270
     */
271 44
    public function setTopColor($colorIndex)
272
    {
273 44
        $this->topBorderColor = $colorIndex;
274 44
    }
275
276
    /**
277
     * Sets the cell's left border color.
278
     *
279
     * @param int $colorIndex Color index
280
     */
281 44
    public function setLeftColor($colorIndex)
282
    {
283 44
        $this->leftBorderColor = $colorIndex;
284 44
    }
285
286
    /**
287
     * Sets the cell's right border color.
288
     *
289
     * @param int $colorIndex Color index
290
     */
291 44
    public function setRightColor($colorIndex)
292
    {
293 44
        $this->rightBorderColor = $colorIndex;
294 44
    }
295
296
    /**
297
     * Sets the cell's diagonal border color.
298
     *
299
     * @param int $colorIndex Color index
300
     */
301 44
    public function setDiagColor($colorIndex)
302
    {
303 44
        $this->_diag_color = $colorIndex;
0 ignored issues
show
Bug Best Practice introduced by
The property _diag_color does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
304 44
    }
305
306
    /**
307
     * Sets the cell's foreground color.
308
     *
309
     * @param int $colorIndex Color index
310
     */
311 44
    public function setFgColor($colorIndex)
312
    {
313 44
        $this->foregroundColor = $colorIndex;
314 44
    }
315
316
    /**
317
     * Sets the cell's background color.
318
     *
319
     * @param int $colorIndex Color index
320
     */
321 44
    public function setBgColor($colorIndex)
322
    {
323 44
        $this->backgroundColor = $colorIndex;
324 44
    }
325
326
    /**
327
     * Sets the index to the number format record
328
     * It can be date, time, currency, etc...
329
     *
330
     * @param int $numberFormatIndex Index to format record
331
     */
332 44
    public function setNumberFormatIndex($numberFormatIndex)
333
    {
334 44
        $this->numberFormatIndex = $numberFormatIndex;
335 44
    }
336
337
    /**
338
     * Set the font index.
339
     *
340
     * @param int $value Font index, note that value 4 does not exist
341
     */
342 44
    public function setFontIndex($value)
343
    {
344 44
        $this->fontIndex = $value;
345 44
    }
346
347
    /**
348
     * Map of BIFF2-BIFF8 codes for border styles.
349
     *
350
     * @var array of int
351
     */
352
    private static $mapBorderStyles = [
353
        Border::BORDER_NONE => 0x00,
354
        Border::BORDER_THIN => 0x01,
355
        Border::BORDER_MEDIUM => 0x02,
356
        Border::BORDER_DASHED => 0x03,
357
        Border::BORDER_DOTTED => 0x04,
358
        Border::BORDER_THICK => 0x05,
359
        Border::BORDER_DOUBLE => 0x06,
360
        Border::BORDER_HAIR => 0x07,
361
        Border::BORDER_MEDIUMDASHED => 0x08,
362
        Border::BORDER_DASHDOT => 0x09,
363
        Border::BORDER_MEDIUMDASHDOT => 0x0A,
364
        Border::BORDER_DASHDOTDOT => 0x0B,
365
        Border::BORDER_MEDIUMDASHDOTDOT => 0x0C,
366
        Border::BORDER_SLANTDASHDOT => 0x0D,
367
    ];
368
369
    /**
370
     * Map border style.
371
     *
372
     * @param string $borderStyle
373
     *
374
     * @return int
375
     */
376 44
    private static function mapBorderStyle($borderStyle)
377
    {
378 44
        if (isset(self::$mapBorderStyles[$borderStyle])) {
379 44
            return self::$mapBorderStyles[$borderStyle];
380
        }
381
382
        return 0x00;
383
    }
384
385
    /**
386
     * Map of BIFF2-BIFF8 codes for fill types.
387
     *
388
     * @var array of int
389
     */
390
    private static $mapFillTypes = [
391
        Fill::FILL_NONE => 0x00,
392
        Fill::FILL_SOLID => 0x01,
393
        Fill::FILL_PATTERN_MEDIUMGRAY => 0x02,
394
        Fill::FILL_PATTERN_DARKGRAY => 0x03,
395
        Fill::FILL_PATTERN_LIGHTGRAY => 0x04,
396
        Fill::FILL_PATTERN_DARKHORIZONTAL => 0x05,
397
        Fill::FILL_PATTERN_DARKVERTICAL => 0x06,
398
        Fill::FILL_PATTERN_DARKDOWN => 0x07,
399
        Fill::FILL_PATTERN_DARKUP => 0x08,
400
        Fill::FILL_PATTERN_DARKGRID => 0x09,
401
        Fill::FILL_PATTERN_DARKTRELLIS => 0x0A,
402
        Fill::FILL_PATTERN_LIGHTHORIZONTAL => 0x0B,
403
        Fill::FILL_PATTERN_LIGHTVERTICAL => 0x0C,
404
        Fill::FILL_PATTERN_LIGHTDOWN => 0x0D,
405
        Fill::FILL_PATTERN_LIGHTUP => 0x0E,
406
        Fill::FILL_PATTERN_LIGHTGRID => 0x0F,
407
        Fill::FILL_PATTERN_LIGHTTRELLIS => 0x10,
408
        Fill::FILL_PATTERN_GRAY125 => 0x11,
409
        Fill::FILL_PATTERN_GRAY0625 => 0x12,
410
        Fill::FILL_GRADIENT_LINEAR => 0x00, // does not exist in BIFF8
411
        Fill::FILL_GRADIENT_PATH => 0x00, // does not exist in BIFF8
412
    ];
413
414
    /**
415
     * Map fill type.
416
     *
417
     * @param string $fillType
418
     *
419
     * @return int
420
     */
421 44
    private static function mapFillType($fillType)
422
    {
423 44
        if (isset(self::$mapFillTypes[$fillType])) {
424 44
            return self::$mapFillTypes[$fillType];
425
        }
426
427
        return 0x00;
428
    }
429
430
    /**
431
     * Map of BIFF2-BIFF8 codes for horizontal alignment.
432
     *
433
     * @var array of int
434
     */
435
    private static $mapHAlignments = [
436
        Alignment::HORIZONTAL_GENERAL => 0,
437
        Alignment::HORIZONTAL_LEFT => 1,
438
        Alignment::HORIZONTAL_CENTER => 2,
439
        Alignment::HORIZONTAL_RIGHT => 3,
440
        Alignment::HORIZONTAL_FILL => 4,
441
        Alignment::HORIZONTAL_JUSTIFY => 5,
442
        Alignment::HORIZONTAL_CENTER_CONTINUOUS => 6,
443
    ];
444
445
    /**
446
     * Map to BIFF2-BIFF8 codes for horizontal alignment.
447
     *
448
     * @param string $hAlign
449
     *
450
     * @return int
451
     */
452 44
    private function mapHAlign($hAlign)
453
    {
454 44
        if (isset(self::$mapHAlignments[$hAlign])) {
455 44
            return self::$mapHAlignments[$hAlign];
456
        }
457
458
        return 0;
459
    }
460
461
    /**
462
     * Map of BIFF2-BIFF8 codes for vertical alignment.
463
     *
464
     * @var array of int
465
     */
466
    private static $mapVAlignments = [
467
        Alignment::VERTICAL_TOP => 0,
468
        Alignment::VERTICAL_CENTER => 1,
469
        Alignment::VERTICAL_BOTTOM => 2,
470
        Alignment::VERTICAL_JUSTIFY => 3,
471
    ];
472
473
    /**
474
     * Map to BIFF2-BIFF8 codes for vertical alignment.
475
     *
476
     * @param string $vAlign
477
     *
478
     * @return int
479
     */
480 44
    private static function mapVAlign($vAlign)
481
    {
482 44
        if (isset(self::$mapVAlignments[$vAlign])) {
483 44
            return self::$mapVAlignments[$vAlign];
484
        }
485
486
        return 2;
487
    }
488
489
    /**
490
     * Map to BIFF8 codes for text rotation angle.
491
     *
492
     * @param int $textRotation
493
     *
494
     * @return int
495
     */
496 44
    private static function mapTextRotation($textRotation)
497
    {
498 44
        if ($textRotation >= 0) {
499 44
            return $textRotation;
500
        } elseif ($textRotation == -165) {
501
            return 255;
502
        } elseif ($textRotation < 0) {
503
            return 90 - $textRotation;
504
        }
505
    }
506
507
    /**
508
     * Map locked.
509
     *
510
     * @param string $locked
511
     *
512
     * @return int
513
     */
514 44
    private static function mapLocked($locked)
515
    {
516 44
        switch ($locked) {
517
            case Protection::PROTECTION_INHERIT:
518 44
                return 1;
519
            case Protection::PROTECTION_PROTECTED:
520
                return 1;
521
            case Protection::PROTECTION_UNPROTECTED:
522 7
                return 0;
523
            default:
524
                return 1;
525
        }
526
    }
527
528
    /**
529
     * Map hidden.
530
     *
531
     * @param string $hidden
532
     *
533
     * @return int
534
     */
535 44
    private static function mapHidden($hidden)
536
    {
537 44
        switch ($hidden) {
538
            case Protection::PROTECTION_INHERIT:
539 41
                return 0;
540
            case Protection::PROTECTION_PROTECTED:
541
                return 1;
542
            case Protection::PROTECTION_UNPROTECTED:
543 4
                return 0;
544
            default:
545
                return 0;
546
        }
547
    }
548
}
549