Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.05% covered (success)
90.05%
1285 / 1427
80.00% covered (warning)
80.00%
16 / 20
CRAP
0.00% covered (danger)
0.00%
0 / 1
MsDoc
90.05% covered (success)
90.05%
1285 / 1427
80.00% covered (warning)
80.00%
16 / 20
243.61
0.00% covered (danger)
0.00%
0 / 1
 load
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 loadOLE
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 getNumInLcb
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getArrayCP
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 readFib
88.51% covered (warning)
88.51%
77 / 87
0.00% covered (danger)
0.00%
0 / 1
7.07
 readBlockFibRgFcLcb
100.00% covered (success)
100.00%
738 / 738
100.00% covered (success)
100.00%
1 / 1
6
 readFibContent
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 readRecordPlcfSed
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
3
 readRecordSttbfFfn
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
1 / 1
7
 readRecordPlcfBtePapx
100.00% covered (success)
100.00%
29 / 29
100.00% covered (success)
100.00%
1 / 1
8
 readRecordPlcfBteChpx
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
1 / 1
6
 readSprm
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 readSprmSpra
90.70% covered (success)
90.70%
39 / 43
0.00% covered (danger)
0.00%
0 / 1
14.16
 readPrl
66.57% covered (warning)
66.57%
239 / 359
0.00% covered (danger)
0.00%
0 / 1
647.88
 loadRecordHeader
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 generatePhpWord
79.49% covered (warning)
79.49%
31 / 39
0.00% covered (danger)
0.00%
0 / 1
23.45
 getInt1d
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getInt2d
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getInt3d
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getInt4d
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3/**
4 * This file is part of PHPWord - A pure PHP library for reading and writing
5 * word processing documents.
6 *
7 * PHPWord is free software distributed under the terms of the GNU Lesser
8 * General Public License version 3 as published by the Free Software Foundation.
9 *
10 * For the full copyright and license information, please read the LICENSE
11 * file that was distributed with this source code. For the full list of
12 * contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
13 *
14 * @see         https://github.com/PHPOffice/PHPWord
15 *
16 * @license     http://www.gnu.org/licenses/lgpl.txt LGPL version 3
17 */
18
19namespace PhpOffice\PhpWord\Reader;
20
21use PhpOffice\PhpWord\PhpWord;
22use PhpOffice\PhpWord\Shared\Drawing;
23use PhpOffice\PhpWord\Shared\OLERead;
24use PhpOffice\PhpWord\Style;
25use stdClass;
26
27/**
28 * Reader for Word97.
29 *
30 * @since 0.10.0
31 */
32class MsDoc extends AbstractReader implements ReaderInterface
33{
34    /**
35     * PhpWord object.
36     *
37     * @var PhpWord
38     */
39    private $phpWord;
40
41    /**
42     * WordDocument Stream.
43     */
44    private $dataWorkDocument;
45
46    /**
47     * 1Table Stream.
48     */
49    private $data1Table;
50
51    /**
52     * Data Stream.
53     */
54    private $dataData;
55
56    /**
57     * Object Pool Stream.
58     */
59    private $dataObjectPool;
60
61    /**
62     * @var stdClass[]
63     */
64    private $arrayCharacters = [];
65
66    /**
67     * @var array
68     */
69    private $arrayFib = [];
70
71    /**
72     * @var string[]
73     */
74    private $arrayFonts = [];
75
76    /**
77     * @var string[]
78     */
79    private $arrayParagraphs = [];
80
81    /**
82     * @var stdClass[]
83     */
84    private $arraySections = [];
85
86    /** @var string */
87    private $summaryInformation;
88
89    /** @var string */
90    private $documentSummaryInformation;
91
92    const VERSION_97 = '97';
93    const VERSION_2000 = '2000';
94    const VERSION_2002 = '2002';
95    const VERSION_2003 = '2003';
96    const VERSION_2007 = '2007';
97
98    const SPRA_VALUE = 10;
99    const SPRA_VALUE_OPPOSITE = 20;
100
101    const OFFICEARTBLIPEMF = 0xF01A;
102    const OFFICEARTBLIPWMF = 0xF01B;
103    const OFFICEARTBLIPPICT = 0xF01C;
104    const OFFICEARTBLIPJPG = 0xF01D;
105    const OFFICEARTBLIPPNG = 0xF01E;
106    const OFFICEARTBLIPDIB = 0xF01F;
107    const OFFICEARTBLIPTIFF = 0xF029;
108    const OFFICEARTBLIPJPEG = 0xF02A;
109
110    const MSOBLIPERROR = 0x00;
111    const MSOBLIPUNKNOWN = 0x01;
112    const MSOBLIPEMF = 0x02;
113    const MSOBLIPWMF = 0x03;
114    const MSOBLIPPICT = 0x04;
115    const MSOBLIPJPEG = 0x05;
116    const MSOBLIPPNG = 0x06;
117    const MSOBLIPDIB = 0x07;
118    const MSOBLIPTIFF = 0x11;
119    const MSOBLIPCMYKJPEG = 0x12;
120
121    /**
122     * Loads PhpWord from file.
123     *
124     * @param string $filename
125     *
126     * @return PhpWord
127     */
128    public function load($filename)
129    {
130        $this->phpWord = new PhpWord();
131
132        $this->loadOLE($filename);
133
134        $this->readFib($this->dataWorkDocument);
135        $this->readFibContent();
136
137        return $this->phpWord;
138    }
139
140    /**
141     * Load an OLE Document.
142     *
143     * @param string $filename
144     */
145    private function loadOLE($filename): void
146    {
147        // OLE reader
148        $ole = new OLERead();
149        $ole->read($filename);
150
151        // Get WorkDocument stream
152        $this->dataWorkDocument = $ole->getStream($ole->wrkdocument);
153        // Get 1Table stream
154        $this->data1Table = $ole->getStream($ole->wrk1Table);
155        // Get Data stream
156        $this->dataData = $ole->getStream($ole->wrkData);
157        // Get Data stream
158        $this->dataObjectPool = $ole->getStream($ole->wrkObjectPool);
159        // Get Summary Information data
160        $this->summaryInformation = $ole->getStream($ole->summaryInformation);
161        // Get Document Summary Information data
162        $this->documentSummaryInformation = $ole->getStream($ole->docSummaryInfos);
163    }
164
165    private function getNumInLcb($lcb, $iSize)
166    {
167        return ($lcb - 4) / (4 + $iSize);
168    }
169
170    private function getArrayCP($data, $posMem, $iNum)
171    {
172        $arrayCP = [];
173        for ($inc = 0; $inc < $iNum; ++$inc) {
174            $arrayCP[$inc] = self::getInt4d($data, $posMem);
175            $posMem += 4;
176        }
177
178        return $arrayCP;
179    }
180
181    /**
182     * @see  http://msdn.microsoft.com/en-us/library/dd949344%28v=office.12%29.aspx
183     * @see  https://igor.io/2012/09/24/binary-parsing.html
184     *
185     * @param string $data
186     */
187    private function readFib($data)
188    {
189        $pos = 0;
190        //----- FibBase
191        // wIdent
192        $pos += 2;
193        // nFib
194        $pos += 2;
195        // unused
196        $pos += 2;
197        // lid : Language Identifier
198        $pos += 2;
199        // pnNext
200        $pos += 2;
201
202        // $mem = self::getInt2d($data, $pos);
203        // $fDot = ($mem >> 15) & 1;
204        // $fGlsy = ($mem >> 14) & 1;
205        // $fComplex = ($mem >> 13) & 1;
206        // $fHasPic = ($mem >> 12) & 1;
207        // $cQuickSaves = ($mem >> 8) & bindec('1111');
208        // $fEncrypted = ($mem >> 7) & 1;
209        // $fWhichTblStm = ($mem >> 6) & 1;
210        // $fReadOnlyRecommended = ($mem >> 5) & 1;
211        // $fWriteReservation = ($mem >> 4) & 1;
212        // $fExtChar = ($mem >> 3) & 1;
213        // $fLoadOverride = ($mem >> 2) & 1;
214        // $fFarEast = ($mem >> 1) & 1;
215        // $fObfuscated = ($mem >> 0) & 1;
216        $pos += 2;
217        // nFibBack
218        $pos += 2;
219        // lKey
220        $pos += 4;
221        // envr
222        ++$pos;
223
224        // $mem = self::getInt1d($data, $pos);
225        // $fMac = ($mem >> 7) & 1;
226        // $fEmptySpecial = ($mem >> 6) & 1;
227        // $fLoadOverridePage = ($mem >> 5) & 1;
228        // $reserved1 = ($mem >> 4) & 1;
229        // $reserved2 = ($mem >> 3) & 1;
230        // $fSpare0 = ($mem >> 0) & bindec('111');
231        ++$pos;
232
233        // reserved3
234        $pos += 2;
235        // reserved4
236        $pos += 2;
237        // reserved5
238        $pos += 4;
239        // reserved6
240        $pos += 4;
241
242        //----- csw
243        $pos += 2;
244
245        //----- fibRgW
246        // reserved1
247        $pos += 2;
248        // reserved2
249        $pos += 2;
250        // reserved3
251        $pos += 2;
252        // reserved4
253        $pos += 2;
254        // reserved5
255        $pos += 2;
256        // reserved6
257        $pos += 2;
258        // reserved7
259        $pos += 2;
260        // reserved8
261        $pos += 2;
262        // reserved9
263        $pos += 2;
264        // reserved10
265        $pos += 2;
266        // reserved11
267        $pos += 2;
268        // reserved12
269        $pos += 2;
270        // reserved13
271        $pos += 2;
272        // lidFE
273        $pos += 2;
274
275        //----- cslw
276        $pos += 2;
277
278        //----- fibRgLw
279        // cbMac
280        $pos += 4;
281        // reserved1
282        $pos += 4;
283        // reserved2
284        $pos += 4;
285        $this->arrayFib['ccpText'] = self::getInt4d($data, $pos);
286        $pos += 4;
287        $this->arrayFib['ccpFtn'] = self::getInt4d($data, $pos);
288        $pos += 4;
289        $this->arrayFib['ccpHdd'] = self::getInt4d($data, $pos);
290        $pos += 4;
291        // reserved3
292        $pos += 4;
293        // ccpAtn
294        $pos += 4;
295        // ccpEdn
296        $pos += 4;
297        // ccpTxbx
298        $pos += 4;
299        // ccpHdrTxbx
300        $pos += 4;
301        // reserved4
302        $pos += 4;
303        // reserved5
304        $pos += 4;
305        // reserved6
306        $pos += 4;
307        // reserved7
308        $pos += 4;
309        // reserved8
310        $pos += 4;
311        // reserved9
312        $pos += 4;
313        // reserved10
314        $pos += 4;
315        // reserved11
316        $pos += 4;
317        // reserved12
318        $pos += 4;
319        // reserved13
320        $pos += 4;
321        // reserved14
322        $pos += 4;
323
324        //----- cbRgFcLcb
325        $cbRgFcLcb = self::getInt2d($data, $pos);
326        $pos += 2;
327        //----- fibRgFcLcbBlob
328        switch ($cbRgFcLcb) {
329            case 0x005D:
330                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_97);
331
332                break;
333            case 0x006C:
334                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_97);
335                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_2000);
336
337                break;
338            case 0x0088:
339                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_97);
340                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_2000);
341                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_2002);
342
343                break;
344            case 0x00A4:
345                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_97);
346                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_2000);
347                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_2002);
348                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_2003);
349
350                break;
351            case 0x00B7:
352                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_97);
353                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_2000);
354                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_2002);
355                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_2003);
356                $pos = $this->readBlockFibRgFcLcb($data, $pos, self::VERSION_2007);
357
358                break;
359        }
360        //----- cswNew
361        $this->arrayFib['cswNew'] = self::getInt2d($data, $pos);
362        $pos += 2;
363
364        if ($this->arrayFib['cswNew'] != 0) {
365            //@todo : fibRgCswNew
366        }
367
368        return $pos;
369    }
370
371    private function readBlockFibRgFcLcb($data, $pos, $version)
372    {
373        if ($version == self::VERSION_97) {
374            $this->arrayFib['fcStshfOrig'] = self::getInt4d($data, $pos);
375            $pos += 4;
376            $this->arrayFib['lcbStshfOrig'] = self::getInt4d($data, $pos);
377            $pos += 4;
378            $this->arrayFib['fcStshf'] = self::getInt4d($data, $pos);
379            $pos += 4;
380            $this->arrayFib['lcbStshf'] = self::getInt4d($data, $pos);
381            $pos += 4;
382            $this->arrayFib['fcPlcffndRef'] = self::getInt4d($data, $pos);
383            $pos += 4;
384            $this->arrayFib['lcbPlcffndRef'] = self::getInt4d($data, $pos);
385            $pos += 4;
386            $this->arrayFib['fcPlcffndTxt'] = self::getInt4d($data, $pos);
387            $pos += 4;
388            $this->arrayFib['lcbPlcffndTxt'] = self::getInt4d($data, $pos);
389            $pos += 4;
390            $this->arrayFib['fcPlcfandRef'] = self::getInt4d($data, $pos);
391            $pos += 4;
392            $this->arrayFib['lcbPlcfandRef'] = self::getInt4d($data, $pos);
393            $pos += 4;
394            $this->arrayFib['fcPlcfandTxt'] = self::getInt4d($data, $pos);
395            $pos += 4;
396            $this->arrayFib['lcbPlcfandTxt '] = self::getInt4d($data, $pos);
397            $pos += 4;
398            $this->arrayFib['fcPlcfSed'] = self::getInt4d($data, $pos);
399            $pos += 4;
400            $this->arrayFib['lcbPlcfSed'] = self::getInt4d($data, $pos);
401            $pos += 4;
402            $this->arrayFib['fcPlcPad'] = self::getInt4d($data, $pos);
403            $pos += 4;
404            $this->arrayFib['lcbPlcPad'] = self::getInt4d($data, $pos);
405            $pos += 4;
406            $this->arrayFib['fcPlcfPhe'] = self::getInt4d($data, $pos);
407            $pos += 4;
408            $this->arrayFib['lcbPlcfPhe'] = self::getInt4d($data, $pos);
409            $pos += 4;
410            $this->arrayFib['fcSttbfGlsy'] = self::getInt4d($data, $pos);
411            $pos += 4;
412            $this->arrayFib['lcbSttbfGlsy'] = self::getInt4d($data, $pos);
413            $pos += 4;
414            $this->arrayFib['fcPlcfGlsy'] = self::getInt4d($data, $pos);
415            $pos += 4;
416            $this->arrayFib['lcbPlcfGlsy'] = self::getInt4d($data, $pos);
417            $pos += 4;
418            $this->arrayFib['fcPlcfHdd'] = self::getInt4d($data, $pos);
419            $pos += 4;
420            $this->arrayFib['lcbPlcfHdd'] = self::getInt4d($data, $pos);
421            $pos += 4;
422            $this->arrayFib['fcPlcfBteChpx'] = self::getInt4d($data, $pos);
423            $pos += 4;
424            $this->arrayFib['lcbPlcfBteChpx'] = self::getInt4d($data, $pos);
425            $pos += 4;
426            $this->arrayFib['fcPlcfBtePapx'] = self::getInt4d($data, $pos);
427            $pos += 4;
428            $this->arrayFib['lcbPlcfBtePapx'] = self::getInt4d($data, $pos);
429            $pos += 4;
430            $this->arrayFib['fcPlcfSea'] = self::getInt4d($data, $pos);
431            $pos += 4;
432            $this->arrayFib['lcbPlcfSea'] = self::getInt4d($data, $pos);
433            $pos += 4;
434            $this->arrayFib['fcSttbfFfn'] = self::getInt4d($data, $pos);
435            $pos += 4;
436            $this->arrayFib['lcbSttbfFfn'] = self::getInt4d($data, $pos);
437            $pos += 4;
438            $this->arrayFib['fcPlcfFldMom'] = self::getInt4d($data, $pos);
439            $pos += 4;
440            $this->arrayFib['lcbPlcfFldMom'] = self::getInt4d($data, $pos);
441            $pos += 4;
442            $this->arrayFib['fcPlcfFldHdr'] = self::getInt4d($data, $pos);
443            $pos += 4;
444            $this->arrayFib['lcbPlcfFldHdr'] = self::getInt4d($data, $pos);
445            $pos += 4;
446            $this->arrayFib['fcPlcfFldFtn'] = self::getInt4d($data, $pos);
447            $pos += 4;
448            $this->arrayFib['lcbPlcfFldFtn'] = self::getInt4d($data, $pos);
449            $pos += 4;
450            $this->arrayFib['fcPlcfFldAtn'] = self::getInt4d($data, $pos);
451            $pos += 4;
452            $this->arrayFib['lcbPlcfFldAtn'] = self::getInt4d($data, $pos);
453            $pos += 4;
454            $this->arrayFib['fcPlcfFldMcr'] = self::getInt4d($data, $pos);
455            $pos += 4;
456            $this->arrayFib['lcbPlcfFldMcr'] = self::getInt4d($data, $pos);
457            $pos += 4;
458            $this->arrayFib['fcSttbfBkmk'] = self::getInt4d($data, $pos);
459            $pos += 4;
460            $this->arrayFib['lcbSttbfBkmk'] = self::getInt4d($data, $pos);
461            $pos += 4;
462            $this->arrayFib['fcPlcfBkf'] = self::getInt4d($data, $pos);
463            $pos += 4;
464            $this->arrayFib['lcbPlcfBkf'] = self::getInt4d($data, $pos);
465            $pos += 4;
466            $this->arrayFib['fcPlcfBkl'] = self::getInt4d($data, $pos);
467            $pos += 4;
468            $this->arrayFib['lcbPlcfBkl'] = self::getInt4d($data, $pos);
469            $pos += 4;
470            $this->arrayFib['fcCmds'] = self::getInt4d($data, $pos);
471            $pos += 4;
472            $this->arrayFib['lcbCmds'] = self::getInt4d($data, $pos);
473            $pos += 4;
474            $this->arrayFib['fcUnused1'] = self::getInt4d($data, $pos);
475            $pos += 4;
476            $this->arrayFib['lcbUnused1'] = self::getInt4d($data, $pos);
477            $pos += 4;
478            $this->arrayFib['fcSttbfMcr'] = self::getInt4d($data, $pos);
479            $pos += 4;
480            $this->arrayFib['lcbSttbfMcr'] = self::getInt4d($data, $pos);
481            $pos += 4;
482            $this->arrayFib['fcPrDrvr'] = self::getInt4d($data, $pos);
483            $pos += 4;
484            $this->arrayFib['lcbPrDrvr'] = self::getInt4d($data, $pos);
485            $pos += 4;
486            $this->arrayFib['fcPrEnvPort'] = self::getInt4d($data, $pos);
487            $pos += 4;
488            $this->arrayFib['lcbPrEnvPort'] = self::getInt4d($data, $pos);
489            $pos += 4;
490            $this->arrayFib['fcPrEnvLand'] = self::getInt4d($data, $pos);
491            $pos += 4;
492            $this->arrayFib['lcbPrEnvLand'] = self::getInt4d($data, $pos);
493            $pos += 4;
494            $this->arrayFib['fcWss'] = self::getInt4d($data, $pos);
495            $pos += 4;
496            $this->arrayFib['lcbWss'] = self::getInt4d($data, $pos);
497            $pos += 4;
498            $this->arrayFib['fcDop'] = self::getInt4d($data, $pos);
499            $pos += 4;
500            $this->arrayFib['lcbDop'] = self::getInt4d($data, $pos);
501            $pos += 4;
502            $this->arrayFib['fcSttbfAssoc'] = self::getInt4d($data, $pos);
503            $pos += 4;
504            $this->arrayFib['lcbSttbfAssoc'] = self::getInt4d($data, $pos);
505            $pos += 4;
506            $this->arrayFib['fcClx'] = self::getInt4d($data, $pos);
507            $pos += 4;
508            $this->arrayFib['lcbClx'] = self::getInt4d($data, $pos);
509            $pos += 4;
510            $this->arrayFib['fcPlcfPgdFtn'] = self::getInt4d($data, $pos);
511            $pos += 4;
512            $this->arrayFib['lcbPlcfPgdFtn'] = self::getInt4d($data, $pos);
513            $pos += 4;
514            $this->arrayFib['fcAutosaveSource'] = self::getInt4d($data, $pos);
515            $pos += 4;
516            $this->arrayFib['lcbAutosaveSource'] = self::getInt4d($data, $pos);
517            $pos += 4;
518            $this->arrayFib['fcGrpXstAtnOwners'] = self::getInt4d($data, $pos);
519            $pos += 4;
520            $this->arrayFib['lcbGrpXstAtnOwners'] = self::getInt4d($data, $pos);
521            $pos += 4;
522            $this->arrayFib['fcSttbfAtnBkmk'] = self::getInt4d($data, $pos);
523            $pos += 4;
524            $this->arrayFib['lcbSttbfAtnBkmk'] = self::getInt4d($data, $pos);
525            $pos += 4;
526            $this->arrayFib['fcUnused2'] = self::getInt4d($data, $pos);
527            $pos += 4;
528            $this->arrayFib['lcbUnused2'] = self::getInt4d($data, $pos);
529            $pos += 4;
530            $this->arrayFib['fcUnused3'] = self::getInt4d($data, $pos);
531            $pos += 4;
532            $this->arrayFib['lcbUnused3'] = self::getInt4d($data, $pos);
533            $pos += 4;
534            $this->arrayFib['fcPlcSpaMom'] = self::getInt4d($data, $pos);
535            $pos += 4;
536            $this->arrayFib['lcbPlcSpaMom'] = self::getInt4d($data, $pos);
537            $pos += 4;
538            $this->arrayFib['fcPlcSpaHdr'] = self::getInt4d($data, $pos);
539            $pos += 4;
540            $this->arrayFib['lcbPlcSpaHdr'] = self::getInt4d($data, $pos);
541            $pos += 4;
542            $this->arrayFib['fcPlcfAtnBkf'] = self::getInt4d($data, $pos);
543            $pos += 4;
544            $this->arrayFib['lcbPlcfAtnBkf'] = self::getInt4d($data, $pos);
545            $pos += 4;
546            $this->arrayFib['fcPlcfAtnBkl'] = self::getInt4d($data, $pos);
547            $pos += 4;
548            $this->arrayFib['lcbPlcfAtnBkl'] = self::getInt4d($data, $pos);
549            $pos += 4;
550            $this->arrayFib['fcPms'] = self::getInt4d($data, $pos);
551            $pos += 4;
552            $this->arrayFib['lcbPms'] = self::getInt4d($data, $pos);
553            $pos += 4;
554            $this->arrayFib['fcFormFldSttbs'] = self::getInt4d($data, $pos);
555            $pos += 4;
556            $this->arrayFib['lcbFormFldSttbs'] = self::getInt4d($data, $pos);
557            $pos += 4;
558            $this->arrayFib['fcPlcfendRef'] = self::getInt4d($data, $pos);
559            $pos += 4;
560            $this->arrayFib['lcbPlcfendRef'] = self::getInt4d($data, $pos);
561            $pos += 4;
562            $this->arrayFib['fcPlcfendTxt'] = self::getInt4d($data, $pos);
563            $pos += 4;
564            $this->arrayFib['lcbPlcfendTxt'] = self::getInt4d($data, $pos);
565            $pos += 4;
566            $this->arrayFib['fcPlcfFldEdn'] = self::getInt4d($data, $pos);
567            $pos += 4;
568            $this->arrayFib['lcbPlcfFldEdn'] = self::getInt4d($data, $pos);
569            $pos += 4;
570            $this->arrayFib['fcUnused4'] = self::getInt4d($data, $pos);
571            $pos += 4;
572            $this->arrayFib['lcbUnused4'] = self::getInt4d($data, $pos);
573            $pos += 4;
574            $this->arrayFib['fcDggInfo'] = self::getInt4d($data, $pos);
575            $pos += 4;
576            $this->arrayFib['lcbDggInfo'] = self::getInt4d($data, $pos);
577            $pos += 4;
578            $this->arrayFib['fcSttbfRMark'] = self::getInt4d($data, $pos);
579            $pos += 4;
580            $this->arrayFib['lcbSttbfRMark'] = self::getInt4d($data, $pos);
581            $pos += 4;
582            $this->arrayFib['fcSttbfCaption'] = self::getInt4d($data, $pos);
583            $pos += 4;
584            $this->arrayFib['lcbSttbfCaption'] = self::getInt4d($data, $pos);
585            $pos += 4;
586            $this->arrayFib['fcSttbfAutoCaption'] = self::getInt4d($data, $pos);
587            $pos += 4;
588            $this->arrayFib['lcbSttbfAutoCaption'] = self::getInt4d($data, $pos);
589            $pos += 4;
590            $this->arrayFib['fcPlcfWkb'] = self::getInt4d($data, $pos);
591            $pos += 4;
592            $this->arrayFib['lcbPlcfWkb'] = self::getInt4d($data, $pos);
593            $pos += 4;
594            $this->arrayFib['fcPlcfSpl'] = self::getInt4d($data, $pos);
595            $pos += 4;
596            $this->arrayFib['lcbPlcfSpl'] = self::getInt4d($data, $pos);
597            $pos += 4;
598            $this->arrayFib['fcPlcftxbxTxt'] = self::getInt4d($data, $pos);
599            $pos += 4;
600            $this->arrayFib['lcbPlcftxbxTxt'] = self::getInt4d($data, $pos);
601            $pos += 4;
602            $this->arrayFib['fcPlcfFldTxbx'] = self::getInt4d($data, $pos);
603            $pos += 4;
604            $this->arrayFib['lcbPlcfFldTxbx'] = self::getInt4d($data, $pos);
605            $pos += 4;
606            $this->arrayFib['fcPlcfHdrtxbxTxt'] = self::getInt4d($data, $pos);
607            $pos += 4;
608            $this->arrayFib['lcbPlcfHdrtxbxTxt'] = self::getInt4d($data, $pos);
609            $pos += 4;
610            $this->arrayFib['fcPlcffldHdrTxbx'] = self::getInt4d($data, $pos);
611            $pos += 4;
612            $this->arrayFib['lcbPlcffldHdrTxbx'] = self::getInt4d($data, $pos);
613            $pos += 4;
614            $this->arrayFib['fcStwUser'] = self::getInt4d($data, $pos);
615            $pos += 4;
616            $this->arrayFib['lcbStwUser'] = self::getInt4d($data, $pos);
617            $pos += 4;
618            $this->arrayFib['fcSttbTtmbd'] = self::getInt4d($data, $pos);
619            $pos += 4;
620            $this->arrayFib['lcbSttbTtmbd'] = self::getInt4d($data, $pos);
621            $pos += 4;
622            $this->arrayFib['fcCookieData'] = self::getInt4d($data, $pos);
623            $pos += 4;
624            $this->arrayFib['lcbCookieData'] = self::getInt4d($data, $pos);
625            $pos += 4;
626            $this->arrayFib['fcPgdMotherOldOld'] = self::getInt4d($data, $pos);
627            $pos += 4;
628            $this->arrayFib['lcbPgdMotherOldOld'] = self::getInt4d($data, $pos);
629            $pos += 4;
630            $this->arrayFib['fcBkdMotherOldOld'] = self::getInt4d($data, $pos);
631            $pos += 4;
632            $this->arrayFib['lcbBkdMotherOldOld'] = self::getInt4d($data, $pos);
633            $pos += 4;
634            $this->arrayFib['fcPgdFtnOldOld'] = self::getInt4d($data, $pos);
635            $pos += 4;
636            $this->arrayFib['lcbPgdFtnOldOld'] = self::getInt4d($data, $pos);
637            $pos += 4;
638            $this->arrayFib['fcBkdFtnOldOld'] = self::getInt4d($data, $pos);
639            $pos += 4;
640            $this->arrayFib['lcbBkdFtnOldOld'] = self::getInt4d($data, $pos);
641            $pos += 4;
642            $this->arrayFib['fcPgdEdnOldOld'] = self::getInt4d($data, $pos);
643            $pos += 4;
644            $this->arrayFib['lcbPgdEdnOldOld'] = self::getInt4d($data, $pos);
645            $pos += 4;
646            $this->arrayFib['fcBkdEdnOldOld'] = self::getInt4d($data, $pos);
647            $pos += 4;
648            $this->arrayFib['lcbBkdEdnOldOld'] = self::getInt4d($data, $pos);
649            $pos += 4;
650            $this->arrayFib['fcSttbfIntlFld'] = self::getInt4d($data, $pos);
651            $pos += 4;
652            $this->arrayFib['lcbSttbfIntlFld'] = self::getInt4d($data, $pos);
653            $pos += 4;
654            $this->arrayFib['fcRouteSlip'] = self::getInt4d($data, $pos);
655            $pos += 4;
656            $this->arrayFib['lcbRouteSlip'] = self::getInt4d($data, $pos);
657            $pos += 4;
658            $this->arrayFib['fcSttbSavedBy'] = self::getInt4d($data, $pos);
659            $pos += 4;
660            $this->arrayFib['lcbSttbSavedBy'] = self::getInt4d($data, $pos);
661            $pos += 4;
662            $this->arrayFib['fcSttbFnm'] = self::getInt4d($data, $pos);
663            $pos += 4;
664            $this->arrayFib['lcbSttbFnm'] = self::getInt4d($data, $pos);
665            $pos += 4;
666            $this->arrayFib['fcPlfLst'] = self::getInt4d($data, $pos);
667            $pos += 4;
668            $this->arrayFib['lcbPlfLst'] = self::getInt4d($data, $pos);
669            $pos += 4;
670            $this->arrayFib['fcPlfLfo'] = self::getInt4d($data, $pos);
671            $pos += 4;
672            $this->arrayFib['lcbPlfLfo'] = self::getInt4d($data, $pos);
673            $pos += 4;
674            $this->arrayFib['fcPlcfTxbxBkd'] = self::getInt4d($data, $pos);
675            $pos += 4;
676            $this->arrayFib['lcbPlcfTxbxBkd'] = self::getInt4d($data, $pos);
677            $pos += 4;
678            $this->arrayFib['fcPlcfTxbxHdrBkd'] = self::getInt4d($data, $pos);
679            $pos += 4;
680            $this->arrayFib['lcbPlcfTxbxHdrBkd'] = self::getInt4d($data, $pos);
681            $pos += 4;
682            $this->arrayFib['fcDocUndoWord9'] = self::getInt4d($data, $pos);
683            $pos += 4;
684            $this->arrayFib['lcbDocUndoWord9'] = self::getInt4d($data, $pos);
685            $pos += 4;
686            $this->arrayFib['fcRgbUse'] = self::getInt4d($data, $pos);
687            $pos += 4;
688            $this->arrayFib['lcbRgbUse'] = self::getInt4d($data, $pos);
689            $pos += 4;
690            $this->arrayFib['fcUsp'] = self::getInt4d($data, $pos);
691            $pos += 4;
692            $this->arrayFib['lcbUsp'] = self::getInt4d($data, $pos);
693            $pos += 4;
694            $this->arrayFib['fcUskf'] = self::getInt4d($data, $pos);
695            $pos += 4;
696            $this->arrayFib['lcbUskf'] = self::getInt4d($data, $pos);
697            $pos += 4;
698            $this->arrayFib['fcPlcupcRgbUse'] = self::getInt4d($data, $pos);
699            $pos += 4;
700            $this->arrayFib['lcbPlcupcRgbUse'] = self::getInt4d($data, $pos);
701            $pos += 4;
702            $this->arrayFib['fcPlcupcUsp'] = self::getInt4d($data, $pos);
703            $pos += 4;
704            $this->arrayFib['lcbPlcupcUsp'] = self::getInt4d($data, $pos);
705            $pos += 4;
706            $this->arrayFib['fcSttbGlsyStyle'] = self::getInt4d($data, $pos);
707            $pos += 4;
708            $this->arrayFib['lcbSttbGlsyStyle'] = self::getInt4d($data, $pos);
709            $pos += 4;
710            $this->arrayFib['fcPlgosl'] = self::getInt4d($data, $pos);
711            $pos += 4;
712            $this->arrayFib['lcbPlgosl'] = self::getInt4d($data, $pos);
713            $pos += 4;
714            $this->arrayFib['fcPlcocx'] = self::getInt4d($data, $pos);
715            $pos += 4;
716            $this->arrayFib['lcbPlcocx'] = self::getInt4d($data, $pos);
717            $pos += 4;
718            $this->arrayFib['fcPlcfBteLvc'] = self::getInt4d($data, $pos);
719            $pos += 4;
720            $this->arrayFib['lcbPlcfBteLvc'] = self::getInt4d($data, $pos);
721            $pos += 4;
722            $this->arrayFib['dwLowDateTime'] = self::getInt4d($data, $pos);
723            $pos += 4;
724            $this->arrayFib['dwHighDateTime'] = self::getInt4d($data, $pos);
725            $pos += 4;
726            $this->arrayFib['fcPlcfLvcPre10'] = self::getInt4d($data, $pos);
727            $pos += 4;
728            $this->arrayFib['lcbPlcfLvcPre10'] = self::getInt4d($data, $pos);
729            $pos += 4;
730            $this->arrayFib['fcPlcfAsumy'] = self::getInt4d($data, $pos);
731            $pos += 4;
732            $this->arrayFib['lcbPlcfAsumy'] = self::getInt4d($data, $pos);
733            $pos += 4;
734            $this->arrayFib['fcPlcfGram'] = self::getInt4d($data, $pos);
735            $pos += 4;
736            $this->arrayFib['lcbPlcfGram'] = self::getInt4d($data, $pos);
737            $pos += 4;
738            $this->arrayFib['fcSttbListNames'] = self::getInt4d($data, $pos);
739            $pos += 4;
740            $this->arrayFib['lcbSttbListNames'] = self::getInt4d($data, $pos);
741            $pos += 4;
742            $this->arrayFib['fcSttbfUssr'] = self::getInt4d($data, $pos);
743            $pos += 4;
744            $this->arrayFib['lcbSttbfUssr'] = self::getInt4d($data, $pos);
745            $pos += 4;
746        }
747        if ($version == self::VERSION_2000) {
748            $this->arrayFib['fcPlcfTch'] = self::getInt4d($data, $pos);
749            $pos += 4;
750            $this->arrayFib['lcbPlcfTch'] = self::getInt4d($data, $pos);
751            $pos += 4;
752            $this->arrayFib['fcRmdThreading'] = self::getInt4d($data, $pos);
753            $pos += 4;
754            $this->arrayFib['lcbRmdThreading'] = self::getInt4d($data, $pos);
755            $pos += 4;
756            $this->arrayFib['fcMid'] = self::getInt4d($data, $pos);
757            $pos += 4;
758            $this->arrayFib['lcbMid'] = self::getInt4d($data, $pos);
759            $pos += 4;
760            $this->arrayFib['fcSttbRgtplc'] = self::getInt4d($data, $pos);
761            $pos += 4;
762            $this->arrayFib['lcbSttbRgtplc'] = self::getInt4d($data, $pos);
763            $pos += 4;
764            $this->arrayFib['fcMsoEnvelope'] = self::getInt4d($data, $pos);
765            $pos += 4;
766            $this->arrayFib['lcbMsoEnvelope'] = self::getInt4d($data, $pos);
767            $pos += 4;
768            $this->arrayFib['fcPlcfLad'] = self::getInt4d($data, $pos);
769            $pos += 4;
770            $this->arrayFib['lcbPlcfLad'] = self::getInt4d($data, $pos);
771            $pos += 4;
772            $this->arrayFib['fcRgDofr'] = self::getInt4d($data, $pos);
773            $pos += 4;
774            $this->arrayFib['lcbRgDofr'] = self::getInt4d($data, $pos);
775            $pos += 4;
776            $this->arrayFib['fcPlcosl'] = self::getInt4d($data, $pos);
777            $pos += 4;
778            $this->arrayFib['lcbPlcosl'] = self::getInt4d($data, $pos);
779            $pos += 4;
780            $this->arrayFib['fcPlcfCookieOld'] = self::getInt4d($data, $pos);
781            $pos += 4;
782            $this->arrayFib['lcbPlcfCookieOld'] = self::getInt4d($data, $pos);
783            $pos += 4;
784            $this->arrayFib['fcPgdMotherOld'] = self::getInt4d($data, $pos);
785            $pos += 4;
786            $this->arrayFib['lcbPgdMotherOld'] = self::getInt4d($data, $pos);
787            $pos += 4;
788            $this->arrayFib['fcBkdMotherOld'] = self::getInt4d($data, $pos);
789            $pos += 4;
790            $this->arrayFib['lcbBkdMotherOld'] = self::getInt4d($data, $pos);
791            $pos += 4;
792            $this->arrayFib['fcPgdFtnOld'] = self::getInt4d($data, $pos);
793            $pos += 4;
794            $this->arrayFib['lcbPgdFtnOld'] = self::getInt4d($data, $pos);
795            $pos += 4;
796            $this->arrayFib['fcBkdFtnOld'] = self::getInt4d($data, $pos);
797            $pos += 4;
798            $this->arrayFib['lcbBkdFtnOld'] = self::getInt4d($data, $pos);
799            $pos += 4;
800            $this->arrayFib['fcPgdEdnOld'] = self::getInt4d($data, $pos);
801            $pos += 4;
802            $this->arrayFib['lcbPgdEdnOld'] = self::getInt4d($data, $pos);
803            $pos += 4;
804            $this->arrayFib['fcBkdEdnOld'] = self::getInt4d($data, $pos);
805            $pos += 4;
806            $this->arrayFib['lcbBkdEdnOld'] = self::getInt4d($data, $pos);
807            $pos += 4;
808        }
809        if ($version == self::VERSION_2002) {
810            $this->arrayFib['fcUnused1'] = self::getInt4d($data, $pos);
811            $pos += 4;
812            $this->arrayFib['lcbUnused1'] = self::getInt4d($data, $pos);
813            $pos += 4;
814            $this->arrayFib['fcPlcfPgp'] = self::getInt4d($data, $pos);
815            $pos += 4;
816            $this->arrayFib['lcbPlcfPgp'] = self::getInt4d($data, $pos);
817            $pos += 4;
818            $this->arrayFib['fcPlcfuim'] = self::getInt4d($data, $pos);
819            $pos += 4;
820            $this->arrayFib['lcbPlcfuim'] = self::getInt4d($data, $pos);
821            $pos += 4;
822            $this->arrayFib['fcPlfguidUim'] = self::getInt4d($data, $pos);
823            $pos += 4;
824            $this->arrayFib['lcbPlfguidUim'] = self::getInt4d($data, $pos);
825            $pos += 4;
826            $this->arrayFib['fcAtrdExtra'] = self::getInt4d($data, $pos);
827            $pos += 4;
828            $this->arrayFib['lcbAtrdExtra'] = self::getInt4d($data, $pos);
829            $pos += 4;
830            $this->arrayFib['fcPlrsid'] = self::getInt4d($data, $pos);
831            $pos += 4;
832            $this->arrayFib['lcbPlrsid'] = self::getInt4d($data, $pos);
833            $pos += 4;
834            $this->arrayFib['fcSttbfBkmkFactoid'] = self::getInt4d($data, $pos);
835            $pos += 4;
836            $this->arrayFib['lcbSttbfBkmkFactoid'] = self::getInt4d($data, $pos);
837            $pos += 4;
838            $this->arrayFib['fcPlcfBkfFactoid'] = self::getInt4d($data, $pos);
839            $pos += 4;
840            $this->arrayFib['lcbPlcfBkfFactoid'] = self::getInt4d($data, $pos);
841            $pos += 4;
842            $this->arrayFib['fcPlcfcookie'] = self::getInt4d($data, $pos);
843            $pos += 4;
844            $this->arrayFib['lcbPlcfcookie'] = self::getInt4d($data, $pos);
845            $pos += 4;
846            $this->arrayFib['fcPlcfBklFactoid'] = self::getInt4d($data, $pos);
847            $pos += 4;
848            $this->arrayFib['lcbPlcfBklFactoid'] = self::getInt4d($data, $pos);
849            $pos += 4;
850            $this->arrayFib['fcFactoidData'] = self::getInt4d($data, $pos);
851            $pos += 4;
852            $this->arrayFib['lcbFactoidData'] = self::getInt4d($data, $pos);
853            $pos += 4;
854            $this->arrayFib['fcDocUndo'] = self::getInt4d($data, $pos);
855            $pos += 4;
856            $this->arrayFib['lcbDocUndo'] = self::getInt4d($data, $pos);
857            $pos += 4;
858            $this->arrayFib['fcSttbfBkmkFcc'] = self::getInt4d($data, $pos);
859            $pos += 4;
860            $this->arrayFib['lcbSttbfBkmkFcc'] = self::getInt4d($data, $pos);
861            $pos += 4;
862            $this->arrayFib['fcPlcfBkfFcc'] = self::getInt4d($data, $pos);
863            $pos += 4;
864            $this->arrayFib['lcbPlcfBkfFcc'] = self::getInt4d($data, $pos);
865            $pos += 4;
866            $this->arrayFib['fcPlcfBklFcc'] = self::getInt4d($data, $pos);
867            $pos += 4;
868            $this->arrayFib['lcbPlcfBklFcc'] = self::getInt4d($data, $pos);
869            $pos += 4;
870            $this->arrayFib['fcSttbfbkmkBPRepairs'] = self::getInt4d($data, $pos);
871            $pos += 4;
872            $this->arrayFib['lcbSttbfbkmkBPRepairs'] = self::getInt4d($data, $pos);
873            $pos += 4;
874            $this->arrayFib['fcPlcfbkfBPRepairs'] = self::getInt4d($data, $pos);
875            $pos += 4;
876            $this->arrayFib['lcbPlcfbkfBPRepairs'] = self::getInt4d($data, $pos);
877            $pos += 4;
878            $this->arrayFib['fcPlcfbklBPRepairs'] = self::getInt4d($data, $pos);
879            $pos += 4;
880            $this->arrayFib['lcbPlcfbklBPRepairs'] = self::getInt4d($data, $pos);
881            $pos += 4;
882            $this->arrayFib['fcPmsNew'] = self::getInt4d($data, $pos);
883            $pos += 4;
884            $this->arrayFib['lcbPmsNew'] = self::getInt4d($data, $pos);
885            $pos += 4;
886            $this->arrayFib['fcODSO'] = self::getInt4d($data, $pos);
887            $pos += 4;
888            $this->arrayFib['lcbODSO'] = self::getInt4d($data, $pos);
889            $pos += 4;
890            $this->arrayFib['fcPlcfpmiOldXP'] = self::getInt4d($data, $pos);
891            $pos += 4;
892            $this->arrayFib['lcbPlcfpmiOldXP'] = self::getInt4d($data, $pos);
893            $pos += 4;
894            $this->arrayFib['fcPlcfpmiNewXP'] = self::getInt4d($data, $pos);
895            $pos += 4;
896            $this->arrayFib['lcbPlcfpmiNewXP'] = self::getInt4d($data, $pos);
897            $pos += 4;
898            $this->arrayFib['fcPlcfpmiMixedXP'] = self::getInt4d($data, $pos);
899            $pos += 4;
900            $this->arrayFib['lcbPlcfpmiMixedXP'] = self::getInt4d($data, $pos);
901            $pos += 4;
902            $this->arrayFib['fcUnused2'] = self::getInt4d($data, $pos);
903            $pos += 4;
904            $this->arrayFib['lcbUnused2'] = self::getInt4d($data, $pos);
905            $pos += 4;
906            $this->arrayFib['fcPlcffactoid'] = self::getInt4d($data, $pos);
907            $pos += 4;
908            $this->arrayFib['lcbPlcffactoid'] = self::getInt4d($data, $pos);
909            $pos += 4;
910            $this->arrayFib['fcPlcflvcOldXP'] = self::getInt4d($data, $pos);
911            $pos += 4;
912            $this->arrayFib['lcbPlcflvcOldXP'] = self::getInt4d($data, $pos);
913            $pos += 4;
914            $this->arrayFib['fcPlcflvcNewXP'] = self::getInt4d($data, $pos);
915            $pos += 4;
916            $this->arrayFib['lcbPlcflvcNewXP'] = self::getInt4d($data, $pos);
917            $pos += 4;
918            $this->arrayFib['fcPlcflvcMixedXP'] = self::getInt4d($data, $pos);
919            $pos += 4;
920            $this->arrayFib['lcbPlcflvcMixedXP'] = self::getInt4d($data, $pos);
921            $pos += 4;
922        }
923        if ($version == self::VERSION_2003) {
924            $this->arrayFib['fcHplxsdr'] = self::getInt4d($data, $pos);
925            $pos += 4;
926            $this->arrayFib['lcbHplxsdr'] = self::getInt4d($data, $pos);
927            $pos += 4;
928            $this->arrayFib['fcSttbfBkmkSdt'] = self::getInt4d($data, $pos);
929            $pos += 4;
930            $this->arrayFib['lcbSttbfBkmkSdt'] = self::getInt4d($data, $pos);
931            $pos += 4;
932            $this->arrayFib['fcPlcfBkfSdt'] = self::getInt4d($data, $pos);
933            $pos += 4;
934            $this->arrayFib['lcbPlcfBkfSdt'] = self::getInt4d($data, $pos);
935            $pos += 4;
936            $this->arrayFib['fcPlcfBklSdt'] = self::getInt4d($data, $pos);
937            $pos += 4;
938            $this->arrayFib['lcbPlcfBklSdt'] = self::getInt4d($data, $pos);
939            $pos += 4;
940            $this->arrayFib['fcCustomXForm'] = self::getInt4d($data, $pos);
941            $pos += 4;
942            $this->arrayFib['lcbCustomXForm'] = self::getInt4d($data, $pos);
943            $pos += 4;
944            $this->arrayFib['fcSttbfBkmkProt'] = self::getInt4d($data, $pos);
945            $pos += 4;
946            $this->arrayFib['lcbSttbfBkmkProt'] = self::getInt4d($data, $pos);
947            $pos += 4;
948            $this->arrayFib['fcPlcfBkfProt'] = self::getInt4d($data, $pos);
949            $pos += 4;
950            $this->arrayFib['lcbPlcfBkfProt'] = self::getInt4d($data, $pos);
951            $pos += 4;
952            $this->arrayFib['fcPlcfBklProt'] = self::getInt4d($data, $pos);
953            $pos += 4;
954            $this->arrayFib['lcbPlcfBklProt'] = self::getInt4d($data, $pos);
955            $pos += 4;
956            $this->arrayFib['fcSttbProtUser'] = self::getInt4d($data, $pos);
957            $pos += 4;
958            $this->arrayFib['lcbSttbProtUser'] = self::getInt4d($data, $pos);
959            $pos += 4;
960            $this->arrayFib['fcUnused'] = self::getInt4d($data, $pos);
961            $pos += 4;
962            $this->arrayFib['lcbUnused'] = self::getInt4d($data, $pos);
963            $pos += 4;
964            $this->arrayFib['fcPlcfpmiOld'] = self::getInt4d($data, $pos);
965            $pos += 4;
966            $this->arrayFib['lcbPlcfpmiOld'] = self::getInt4d($data, $pos);
967            $pos += 4;
968            $this->arrayFib['fcPlcfpmiOldInline'] = self::getInt4d($data, $pos);
969            $pos += 4;
970            $this->arrayFib['lcbPlcfpmiOldInline'] = self::getInt4d($data, $pos);
971            $pos += 4;
972            $this->arrayFib['fcPlcfpmiNew'] = self::getInt4d($data, $pos);
973            $pos += 4;
974            $this->arrayFib['lcbPlcfpmiNew'] = self::getInt4d($data, $pos);
975            $pos += 4;
976            $this->arrayFib['fcPlcfpmiNewInline'] = self::getInt4d($data, $pos);
977            $pos += 4;
978            $this->arrayFib['lcbPlcfpmiNewInline'] = self::getInt4d($data, $pos);
979            $pos += 4;
980            $this->arrayFib['fcPlcflvcOld'] = self::getInt4d($data, $pos);
981            $pos += 4;
982            $this->arrayFib['lcbPlcflvcOld'] = self::getInt4d($data, $pos);
983            $pos += 4;
984            $this->arrayFib['fcPlcflvcOldInline'] = self::getInt4d($data, $pos);
985            $pos += 4;
986            $this->arrayFib['lcbPlcflvcOldInline'] = self::getInt4d($data, $pos);
987            $pos += 4;
988            $this->arrayFib['fcPlcflvcNew'] = self::getInt4d($data, $pos);
989            $pos += 4;
990            $this->arrayFib['lcbPlcflvcNew'] = self::getInt4d($data, $pos);
991            $pos += 4;
992            $this->arrayFib['fcPlcflvcNewInline'] = self::getInt4d($data, $pos);
993            $pos += 4;
994            $this->arrayFib['lcbPlcflvcNewInline'] = self::getInt4d($data, $pos);
995            $pos += 4;
996            $this->arrayFib['fcPgdMother'] = self::getInt4d($data, $pos);
997            $pos += 4;
998            $this->arrayFib['lcbPgdMother'] = self::getInt4d($data, $pos);
999            $pos += 4;
1000            $this->arrayFib['fcBkdMother'] = self::getInt4d($data, $pos);
1001            $pos += 4;
1002            $this->arrayFib['lcbBkdMother'] = self::getInt4d($data, $pos);
1003            $pos += 4;
1004            $this->arrayFib['fcAfdMother'] = self::getInt4d($data, $pos);
1005            $pos += 4;
1006            $this->arrayFib['lcbAfdMother'] = self::getInt4d($data, $pos);
1007            $pos += 4;
1008            $this->arrayFib['fcPgdFtn'] = self::getInt4d($data, $pos);
1009            $pos += 4;
1010            $this->arrayFib['lcbPgdFtn'] = self::getInt4d($data, $pos);
1011            $pos += 4;
1012            $this->arrayFib['fcBkdFtn'] = self::getInt4d($data, $pos);
1013            $pos += 4;
1014            $this->arrayFib['lcbBkdFtn'] = self::getInt4d($data, $pos);
1015            $pos += 4;
1016            $this->arrayFib['fcAfdFtn'] = self::getInt4d($data, $pos);
1017            $pos += 4;
1018            $this->arrayFib['lcbAfdFtn'] = self::getInt4d($data, $pos);
1019            $pos += 4;
1020            $this->arrayFib['fcPgdEdn'] = self::getInt4d($data, $pos);
1021            $pos += 4;
1022            $this->arrayFib['lcbPgdEdn'] = self::getInt4d($data, $pos);
1023            $pos += 4;
1024            $this->arrayFib['fcBkdEdn'] = self::getInt4d($data, $pos);
1025            $pos += 4;
1026            $this->arrayFib['lcbBkdEdn'] = self::getInt4d($data, $pos);
1027            $pos += 4;
1028            $this->arrayFib['fcAfdEdn'] = self::getInt4d($data, $pos);
1029            $pos += 4;
1030            $this->arrayFib['lcbAfdEdn'] = self::getInt4d($data, $pos);
1031            $pos += 4;
1032            $this->arrayFib['fcAfd'] = self::getInt4d($data, $pos);
1033            $pos += 4;
1034            $this->arrayFib['lcbAfd'] = self::getInt4d($data, $pos);
1035            $pos += 4;
1036        }
1037        if ($version == self::VERSION_2007) {
1038            $this->arrayFib['fcPlcfmthd'] = self::getInt4d($data, $pos);
1039            $pos += 4;
1040            $this->arrayFib['lcbPlcfmthd'] = self::getInt4d($data, $pos);
1041            $pos += 4;
1042            $this->arrayFib['fcSttbfBkmkMoveFrom'] = self::getInt4d($data, $pos);
1043            $pos += 4;
1044            $this->arrayFib['lcbSttbfBkmkMoveFrom'] = self::getInt4d($data, $pos);
1045            $pos += 4;
1046            $this->arrayFib['fcPlcfBkfMoveFrom'] = self::getInt4d($data, $pos);
1047            $pos += 4;
1048            $this->arrayFib['lcbPlcfBkfMoveFrom'] = self::getInt4d($data, $pos);
1049            $pos += 4;
1050            $this->arrayFib['fcPlcfBklMoveFrom'] = self::getInt4d($data, $pos);
1051            $pos += 4;
1052            $this->arrayFib['lcbPlcfBklMoveFrom'] = self::getInt4d($data, $pos);
1053            $pos += 4;
1054            $this->arrayFib['fcSttbfBkmkMoveTo'] = self::getInt4d($data, $pos);
1055            $pos += 4;
1056            $this->arrayFib['lcbSttbfBkmkMoveTo'] = self::getInt4d($data, $pos);
1057            $pos += 4;
1058            $this->arrayFib['fcPlcfBkfMoveTo'] = self::getInt4d($data, $pos);
1059            $pos += 4;
1060            $this->arrayFib['lcbPlcfBkfMoveTo'] = self::getInt4d($data, $pos);
1061            $pos += 4;
1062            $this->arrayFib['fcPlcfBklMoveTo'] = self::getInt4d($data, $pos);
1063            $pos += 4;
1064            $this->arrayFib['lcbPlcfBklMoveTo'] = self::getInt4d($data, $pos);
1065            $pos += 4;
1066            $this->arrayFib['fcUnused1'] = self::getInt4d($data, $pos);
1067            $pos += 4;
1068            $this->arrayFib['lcbUnused1'] = self::getInt4d($data, $pos);
1069            $pos += 4;
1070            $this->arrayFib['fcUnused2'] = self::getInt4d($data, $pos);
1071            $pos += 4;
1072            $this->arrayFib['lcbUnused2'] = self::getInt4d($data, $pos);
1073            $pos += 4;
1074            $this->arrayFib['fcUnused3'] = self::getInt4d($data, $pos);
1075            $pos += 4;
1076            $this->arrayFib['lcbUnused3'] = self::getInt4d($data, $pos);
1077            $pos += 4;
1078            $this->arrayFib['fcSttbfBkmkArto'] = self::getInt4d($data, $pos);
1079            $pos += 4;
1080            $this->arrayFib['lcbSttbfBkmkArto'] = self::getInt4d($data, $pos);
1081            $pos += 4;
1082            $this->arrayFib['fcPlcfBkfArto'] = self::getInt4d($data, $pos);
1083            $pos += 4;
1084            $this->arrayFib['lcbPlcfBkfArto'] = self::getInt4d($data, $pos);
1085            $pos += 4;
1086            $this->arrayFib['fcPlcfBklArto'] = self::getInt4d($data, $pos);
1087            $pos += 4;
1088            $this->arrayFib['lcbPlcfBklArto'] = self::getInt4d($data, $pos);
1089            $pos += 4;
1090            $this->arrayFib['fcArtoData'] = self::getInt4d($data, $pos);
1091            $pos += 4;
1092            $this->arrayFib['lcbArtoData'] = self::getInt4d($data, $pos);
1093            $pos += 4;
1094            $this->arrayFib['fcUnused4'] = self::getInt4d($data, $pos);
1095            $pos += 4;
1096            $this->arrayFib['lcbUnused4'] = self::getInt4d($data, $pos);
1097            $pos += 4;
1098            $this->arrayFib['fcUnused5'] = self::getInt4d($data, $pos);
1099            $pos += 4;
1100            $this->arrayFib['lcbUnused5'] = self::getInt4d($data, $pos);
1101            $pos += 4;
1102            $this->arrayFib['fcUnused6'] = self::getInt4d($data, $pos);
1103            $pos += 4;
1104            $this->arrayFib['lcbUnused6'] = self::getInt4d($data, $pos);
1105            $pos += 4;
1106            $this->arrayFib['fcOssTheme'] = self::getInt4d($data, $pos);
1107            $pos += 4;
1108            $this->arrayFib['lcbOssTheme'] = self::getInt4d($data, $pos);
1109            $pos += 4;
1110            $this->arrayFib['fcColorSchemeMapping'] = self::getInt4d($data, $pos);
1111            $pos += 4;
1112            $this->arrayFib['lcbColorSchemeMapping'] = self::getInt4d($data, $pos);
1113            $pos += 4;
1114        }
1115
1116        return $pos;
1117    }
1118
1119    private function readFibContent(): void
1120    {
1121        // Informations about Font
1122        $this->readRecordSttbfFfn();
1123
1124        // Informations about page
1125        $this->readRecordPlcfSed();
1126
1127        // reading paragraphs
1128        //@see  https://github.com/notmasteryet/CompoundFile/blob/ec118f354efebdee9102e41b5b7084fce81125b0/WordFileReader/WordDocument.cs#L86
1129        $this->readRecordPlcfBtePapx();
1130
1131        // reading character formattings
1132        //@see  https://github.com/notmasteryet/CompoundFile/blob/ec118f354efebdee9102e41b5b7084fce81125b0/WordFileReader/WordDocument.cs#L94
1133        $this->readRecordPlcfBteChpx();
1134
1135        $this->generatePhpWord();
1136    }
1137
1138    /**
1139     * Section and information about them.
1140     *
1141     * @see  http://msdn.microsoft.com/en-us/library/dd924458%28v=office.12%29.aspx
1142     */
1143    private function readRecordPlcfSed(): void
1144    {
1145        $posMem = $this->arrayFib['fcPlcfSed'];
1146        // PlcfSed
1147        // PlcfSed : aCP
1148        $aCP = [];
1149        $aCP[0] = self::getInt4d($this->data1Table, $posMem);
1150        $posMem += 4;
1151        $aCP[1] = self::getInt4d($this->data1Table, $posMem);
1152        $posMem += 4;
1153
1154        // PlcfSed : aSed
1155        //@see  http://msdn.microsoft.com/en-us/library/dd950194%28v=office.12%29.aspx
1156        $numSed = $this->getNumInLcb($this->arrayFib['lcbPlcfSed'], 12);
1157
1158        $aSed = [];
1159        for ($iInc = 0; $iInc < $numSed; ++$iInc) {
1160            // Sed : http://msdn.microsoft.com/en-us/library/dd950982%28v=office.12%29.aspx
1161            // fn
1162            $posMem += 2;
1163            // fnMpr
1164            $aSed[$iInc] = self::getInt4d($this->data1Table, $posMem);
1165            $posMem += 4;
1166            // fnMpr
1167            $posMem += 2;
1168            // fcMpr
1169            $posMem += 4;
1170        }
1171
1172        foreach ($aSed as $offsetSed) {
1173            // Sepx : http://msdn.microsoft.com/en-us/library/dd921348%28v=office.12%29.aspx
1174            $cb = self::getInt2d($this->dataWorkDocument, $offsetSed);
1175            $offsetSed += 2;
1176
1177            $oStylePrl = $this->readPrl($this->dataWorkDocument, $offsetSed, $cb);
1178            $offsetSed += $oStylePrl->length;
1179
1180            $this->arraySections[] = $oStylePrl;
1181        }
1182    }
1183
1184    /**
1185     * Specifies the fonts that are used in the document.
1186     *
1187     * @see  http://msdn.microsoft.com/en-us/library/dd943880%28v=office.12%29.aspx
1188     */
1189    private function readRecordSttbfFfn(): void
1190    {
1191        $posMem = $this->arrayFib['fcSttbfFfn'];
1192
1193        $cData = self::getInt2d($this->data1Table, $posMem);
1194        $posMem += 2;
1195        $cbExtra = self::getInt2d($this->data1Table, $posMem);
1196        $posMem += 2;
1197
1198        if ($cData < 0x7FF0 && $cbExtra == 0) {
1199            for ($inc = 0; $inc < $cData; ++$inc) {
1200                // len
1201                ++$posMem;
1202                // ffid
1203                ++$posMem;
1204                // wWeight (400 : Normal - 700 bold)
1205                $posMem += 2;
1206                // chs
1207                ++$posMem;
1208                // ixchSzAlt
1209                $ixchSzAlt = self::getInt1d($this->data1Table, $posMem);
1210                ++$posMem;
1211                // panose
1212                $posMem += 10;
1213                // fs
1214                $posMem += 24;
1215                // xszFfn
1216                $xszFfn = '';
1217                do {
1218                    $char = self::getInt2d($this->data1Table, $posMem);
1219                    $posMem += 2;
1220                    if ($char > 0) {
1221                        $xszFfn .= chr($char);
1222                    }
1223                } while ($char != 0);
1224                // xszAlt
1225                $xszAlt = '';
1226                if ($ixchSzAlt > 0) {
1227                    do {
1228                        $char = self::getInt2d($this->data1Table, $posMem);
1229                        $posMem += 2;
1230                        if ($char == 0) {
1231                            break;
1232                        }
1233                        $xszAlt .= chr($char);
1234                    } while ($char != 0);
1235                }
1236                $this->arrayFonts[] = [
1237                    'main' => $xszFfn,
1238                    'alt' => $xszAlt,
1239                ];
1240            }
1241        }
1242    }
1243
1244    /**
1245     * Paragraph and information about them.
1246     *
1247     * @see  http://msdn.microsoft.com/en-us/library/dd908569%28v=office.12%29.aspx
1248     */
1249    private function readRecordPlcfBtePapx(): void
1250    {
1251        $posMem = $this->arrayFib['fcPlcfBtePapx'];
1252        $num = $this->getNumInLcb($this->arrayFib['lcbPlcfBtePapx'], 4);
1253        $posMem += 4 * ($num + 1);
1254        $arrAPnBtePapx = $this->getArrayCP($this->data1Table, $posMem, $num);
1255        $posMem += 4 * $num;
1256
1257        foreach ($arrAPnBtePapx as $aPnBtePapx) {
1258            $offsetBase = $aPnBtePapx * 512;
1259            $offset = $offsetBase;
1260
1261            $string = '';
1262
1263            $numRun = self::getInt1d($this->dataWorkDocument, $offset + 511);
1264            $arrayRGFC = [];
1265            for ($inc = 0; $inc <= $numRun; ++$inc) {
1266                $arrayRGFC[$inc] = self::getInt4d($this->dataWorkDocument, $offset);
1267                $offset += 4;
1268            }
1269            $arrayRGB = [];
1270            for ($inc = 1; $inc <= $numRun; ++$inc) {
1271                // @see  http://msdn.microsoft.com/en-us/library/dd925804(v=office.12).aspx
1272                $arrayRGB[$inc] = self::getInt1d($this->dataWorkDocument, $offset);
1273                ++$offset;
1274                // reserved
1275                $offset += 12;
1276            }
1277
1278            foreach (array_keys($arrayRGFC) as $key) {
1279                if (!isset($arrayRGFC[$key + 1])) {
1280                    break;
1281                }
1282                $strLen = $arrayRGFC[$key + 1] - $arrayRGFC[$key] - 1;
1283                for ($inc = 0; $inc < ($strLen * 2); ++$inc) {
1284                    $byte = self::getInt2d($this->dataWorkDocument, $arrayRGFC[$key] + ($inc * 2));
1285                    if ($byte > 0) {
1286                        $string .= mb_chr($byte, 'UTF-8');
1287                    } else {
1288                        break;
1289                    }
1290                }
1291            }
1292            $this->arrayParagraphs[] = $string;
1293
1294            //@todo readPrl for paragraphs
1295            /*// use $this->readPrl()
1296            foreach ($arrayRGB as $key => $rgb) {
1297                $offset = $offsetBase + ($rgb * 2);
1298
1299                $cb = self::getInt1d($this->dataWorkDocument, $offset);
1300                $offset += 1;
1301                print_r('$cb : '.$cb.PHP_EOL);
1302                if ($cb == 0) {
1303                    $cb = self::getInt1d($this->dataWorkDocument, $offset);
1304                    $cb = $cb * 2;
1305                    $offset += 1;
1306                    print_r('$cb0 : '.$cb.PHP_EOL);
1307                } else {
1308                    $cb = $cb * 2 - 1;
1309                    print_r('$cbD : '.$cb.PHP_EOL);
1310                }
1311                $istd = self::getInt2d($this->dataWorkDocument, $offset);
1312                $offset += 2;
1313                $cb -= 2;
1314                print_r('$istd : '.$istd.($istd == 0 ? ' (Normal)' : '').PHP_EOL);
1315                if ($cb > 0) {
1316                    do{
1317                        $sprm = self::getInt2d($this->dataWorkDocument, $offset);
1318                        $offset += 2;
1319                        $cb -= 2;
1320                        $sprm_IsPmd = $sprm & 0x01FF;
1321                        $sprm_F = ($sprm/512) & 0x0001;
1322                        $sprm_Sgc = ($sprm/1024) & 0x0007;
1323                        $sprm_Spra = ($sprm/8192);
1324
1325                        print_r('$sprm : 0x'.dechex($sprm).PHP_EOL);
1326                        print_r('$sprm.ispmd : 0x'.dechex($sprm_IsPmd).PHP_EOL);
1327                        print_r('$sprm.f : 0x'.dechex($sprm_F).PHP_EOL);
1328                        print_r('$sprm.sgc : 0x'.dechex($sprm_Sgc));
1329                        switch (dechex($sprm_Sgc)) {
1330                            case 0x01:
1331                                print_r(' (Paragraph property)');
1332                                break;
1333                            case 0x02:
1334                                print_r(' (Character property)');
1335                                break;
1336                            case 0x03:
1337                                print_r(' (Picture property)');
1338                                break;
1339                            case 0x04:
1340                                print_r(' (Section property)');
1341                                break;
1342                            case 0x05:
1343                                print_r(' (Table property)');
1344                                break;
1345                        }
1346                        print_r(PHP_EOL);
1347                        print_r('$sprm.spra : 0x'.dechex($sprm_Spra).PHP_EOL);
1348                        switch (dechex($sprm_Spra)) {
1349                            case 0x0:
1350                                $operand = self::getInt1d($this->dataWorkDocument, $offset);
1351                                $offset += 1;
1352                                $cb -= 1;
1353                                switch (dechex($operand)) {
1354                                    case 0x00:
1355                                        $operand = 'OFF';
1356                                        break;
1357                                    case 0x01:
1358                                        $operand = 'ON';
1359                                        break;
1360                                    case 0x80:
1361                                        $operand = 'CURRENT VALUE';
1362                                        print_r(''.PHP_EOL.PHP_EOL);
1363                                        break;
1364                                    case 0x81:
1365                                        $operand = 'OPPOSITE OF THE CURRENT VALUE';
1366                                        break;
1367                                }
1368                                break;
1369                            case 0x1:
1370                                $operand = self::getInt1d($this->dataWorkDocument, $offset);
1371                                $offset += 1;
1372                                $cb -= 1;
1373                                print_r('$operand : 0x'.dechex($operand).PHP_EOL);
1374                                break;
1375                            case 0x2:
1376                            case 0x4:
1377                            case 0x5:
1378                                $operand = self::getInt2d($this->dataWorkDocument, $offset);
1379                                $offset += 2;
1380                                $cb -= 2;
1381                                print_r('$operand : 0x'.dechex($operand).PHP_EOL);
1382                                break;
1383                            case 0x3:
1384                                if ($sprm_IsPmd != 0x70) {
1385                                    $operand = self::getInt4d($this->dataWorkDocument, $offset);
1386                                    $offset += 4;
1387                                    $cb -= 4;
1388                                    print_r('$operand : 0x'.dechex($operand).PHP_EOL);
1389                                }
1390                                break;
1391                            case 0x7:
1392                                $operand = self::getInt3d($this->dataWorkDocument, $offset);
1393                                $offset += 3;
1394                                $cb -= 3;
1395                                print_r('$operand : 0x'.dechex($operand).PHP_EOL);
1396                                break;
1397                            default:
1398                                print_r('YO YO YO : '.PHP_EOL);
1399                        }
1400
1401                        //
1402                        switch (dechex($sprm_Sgc)) {
1403                            case 0x01: // Sprm is modifying a paragraph property.
1404                                switch ($sprm_IsPmd) {
1405                                    case 0x0A: // sprmPIlvl
1406                                        print_r('sprmPIlvl : '.$operand.PHP_EOL.PHP_EOL);
1407                                        break;
1408                                    case 0x0B: // sprmPIlfo
1409                                        print_r('sprmPIlfo : '.$operand.PHP_EOL.PHP_EOL);
1410                                        break;
1411                                    default:
1412                                        print_r('$sprm_IsPmd(1) : '.$sprm_IsPmd.PHP_EOL.PHP_EOL);
1413                                        break;
1414                                }
1415                                break;
1416                            case 0x02: // Sprm is modifying a character property.
1417                                switch ($sprm_IsPmd) {
1418                                    default:
1419                                        print_r('$sprm_IsPmd(2) : '.$sprm_IsPmd.PHP_EOL.PHP_EOL);
1420                                        break;
1421                                }
1422                                break;
1423                            case 0x03: // Sprm is modifying a picture property.
1424                                switch ($sprm_IsPmd) {
1425                                    default:
1426                                        print_r('$sprm_IsPmd(3) : '.$sprm_IsPmd.PHP_EOL.PHP_EOL);
1427                                        break;
1428                                }
1429                                break;
1430                            case 0x04: // Sprm is modifying a section property.
1431                                switch ($sprm_IsPmd) {
1432                                    default:
1433                                        print_r('$sprm_IsPmd(4) : '.$sprm_IsPmd.PHP_EOL.PHP_EOL);
1434                                        break;
1435                                }
1436                                break;
1437                            case 0x05: // Sprm is modifying a table property.
1438                                switch ($sprm_IsPmd) {
1439                                    default:
1440                                        print_r('$sprm_IsPmd(4) : '.$sprm_IsPmd.PHP_EOL.PHP_EOL);
1441                                        break;
1442                                }
1443                                break;
1444                            default:
1445                                print_r('$sprm_Sgc : '.dechex($sprm_Sgc).PHP_EOL.PHP_EOL);
1446                                break;
1447                        }
1448                    } while ($cb > 0);
1449                } else {
1450                    if ($istd > 0) {
1451                        // @todo : Determining Properties of a Paragraph Style
1452                        # @see  http://msdn.microsoft.com/en-us/library/dd948631%28v=office.12%29.aspx
1453                    }
1454                }
1455            }*/
1456        }
1457    }
1458
1459    /**
1460     * Character formatting properties to text in a document.
1461     *
1462     * @see  http://msdn.microsoft.com/en-us/library/dd907108%28v=office.12%29.aspx
1463     */
1464    private function readRecordPlcfBteChpx(): void
1465    {
1466        $posMem = $this->arrayFib['fcPlcfBteChpx'];
1467        $num = $this->getNumInLcb($this->arrayFib['lcbPlcfBteChpx'], 4);
1468        $aPnBteChpx = [];
1469        for ($inc = 0; $inc <= $num; ++$inc) {
1470            $aPnBteChpx[$inc] = self::getInt4d($this->data1Table, $posMem);
1471            $posMem += 4;
1472        }
1473        $pnFkpChpx = self::getInt4d($this->data1Table, $posMem);
1474        $posMem += 4;
1475
1476        $offsetBase = $pnFkpChpx * 512;
1477        $offset = $offsetBase;
1478
1479        // ChpxFkp
1480        // @see  http://msdn.microsoft.com/en-us/library/dd910989%28v=office.12%29.aspx
1481        $numRGFC = self::getInt1d($this->dataWorkDocument, $offset + 511);
1482        $arrayRGFC = [];
1483        for ($inc = 0; $inc <= $numRGFC; ++$inc) {
1484            $arrayRGFC[$inc] = self::getInt4d($this->dataWorkDocument, $offset);
1485            $offset += 4;
1486        }
1487
1488        $arrayRGB = [];
1489        for ($inc = 1; $inc <= $numRGFC; ++$inc) {
1490            $arrayRGB[$inc] = self::getInt1d($this->dataWorkDocument, $offset);
1491            ++$offset;
1492        }
1493
1494        $start = 0;
1495        foreach ($arrayRGB as $keyRGB => $rgb) {
1496            $oStyle = new stdClass();
1497            $oStyle->pos_start = $start;
1498            $oStyle->pos_len = (int) ceil((($arrayRGFC[$keyRGB] - 1) - $arrayRGFC[$keyRGB - 1]) / 2);
1499            $start += $oStyle->pos_len;
1500
1501            if ($rgb > 0) {
1502                // Chp Structure
1503                // @see  http://msdn.microsoft.com/en-us/library/dd772849%28v=office.12%29.aspx
1504                $posRGB = $offsetBase + $rgb * 2;
1505
1506                $cb = self::getInt1d($this->dataWorkDocument, $posRGB);
1507                ++$posRGB;
1508
1509                $oStyle->style = $this->readPrl($this->dataWorkDocument, $posRGB, $cb);
1510                $posRGB += $oStyle->style->length;
1511            }
1512            $this->arrayCharacters[] = $oStyle;
1513        }
1514    }
1515
1516    /**
1517     * @return stdClass
1518     */
1519    private function readSprm($sprm)
1520    {
1521        $oSprm = new stdClass();
1522        $oSprm->isPmd = $sprm & 0x01FF;
1523        $oSprm->f = (int) ($sprm / 512) & 0x0001;
1524        $oSprm->sgc = (int) ($sprm / 1024) & 0x0007;
1525        $oSprm->spra = (int) ($sprm / 8192);
1526
1527        return $oSprm;
1528    }
1529
1530    /**
1531     * @param string $data
1532     * @param int $pos
1533     * @param stdClass $oSprm
1534     *
1535     * @return array
1536     */
1537    private function readSprmSpra($data, $pos, $oSprm)
1538    {
1539        $length = 0;
1540        $operand = null;
1541
1542        switch (dechex($oSprm->spra)) {
1543            case 0x0:
1544                $operand = self::getInt1d($data, $pos);
1545                $length = 1;
1546                switch (dechex($operand)) {
1547                    case 0x00:
1548                        $operand = false;
1549
1550                        break;
1551                    case 0x01:
1552                        $operand = true;
1553
1554                        break;
1555                    case 0x80:
1556                        $operand = self::SPRA_VALUE;
1557
1558                        break;
1559                    case 0x81:
1560                        $operand = self::SPRA_VALUE_OPPOSITE;
1561
1562                        break;
1563                }
1564
1565                break;
1566            case 0x1:
1567                $operand = self::getInt1d($data, $pos);
1568                $length = 1;
1569
1570                break;
1571            case 0x2:
1572            case 0x4:
1573            case 0x5:
1574                $operand = self::getInt2d($data, $pos);
1575                $length = 2;
1576
1577                break;
1578            case 0x3:
1579                if ($oSprm->isPmd != 0x70) {
1580                    $operand = self::getInt4d($data, $pos);
1581                    $length = 4;
1582                }
1583
1584                break;
1585            case 0x7:
1586                $operand = self::getInt3d($data, $pos);
1587                $length = 3;
1588
1589                break;
1590            default:
1591                // print_r('YO YO YO : '.PHP_EOL);
1592        }
1593
1594        return [
1595            'length' => $length,
1596            'operand' => $operand,
1597        ];
1598    }
1599
1600    /**
1601     * @param $data int
1602     * @param $pos int
1603     * @param $cbNum int
1604     *
1605     * @return stdClass
1606     *
1607     * @see  http://msdn.microsoft.com/en-us/library/dd772849%28v=office.12%29.aspx
1608     */
1609    private function readPrl($data, $pos, $cbNum)
1610    {
1611        $posStart = $pos;
1612        $oStylePrl = new stdClass();
1613
1614        // Variables
1615        $sprmCPicLocation = null;
1616        $sprmCFData = null;
1617        //$sprmCFSpec = null;
1618
1619        do {
1620            // Variables
1621            $operand = null;
1622
1623            $sprm = self::getInt2d($data, $pos);
1624            $oSprm = $this->readSprm($sprm);
1625            $pos += 2;
1626            $cbNum -= 2;
1627
1628            $arrayReturn = $this->readSprmSpra($data, $pos, $oSprm);
1629            $pos += $arrayReturn['length'];
1630            $cbNum -= $arrayReturn['length'];
1631            $operand = $arrayReturn['operand'];
1632
1633            switch (dechex($oSprm->sgc)) {
1634                // Paragraph property
1635                case 0x01:
1636                    break;
1637                    // Character property
1638                case 0x02:
1639                    if (!isset($oStylePrl->styleFont)) {
1640                        $oStylePrl->styleFont = [];
1641                    }
1642                    switch ($oSprm->isPmd) {
1643                        // sprmCFRMarkIns
1644                        case 0x01:
1645                            break;
1646                            // sprmCFFldVanish
1647                        case 0x02:
1648                            break;
1649                            // sprmCPicLocation
1650                        case 0x03:
1651                            $sprmCPicLocation = $operand;
1652
1653                            break;
1654                            // sprmCFData
1655                        case 0x06:
1656                            $sprmCFData = dechex($operand) != 0x00;
1657
1658                            break;
1659                            // sprmCFItalic
1660                        case 0x36:
1661                            // By default, text is not italicized.
1662                            switch ($operand) {
1663                                case false:
1664                                case true:
1665                                    $oStylePrl->styleFont['italic'] = $operand;
1666
1667                                    break;
1668                                case self::SPRA_VALUE:
1669                                    $oStylePrl->styleFont['italic'] = false;
1670
1671                                    break;
1672                                case self::SPRA_VALUE_OPPOSITE:
1673                                    $oStylePrl->styleFont['italic'] = true;
1674
1675                                    break;
1676                            }
1677
1678                            break;
1679                            // sprmCIstd
1680                        case 0x30:
1681                            //print_r('sprmCIstd : '.dechex($operand).PHP_EOL.PHP_EOL);
1682                            break;
1683                            // sprmCFBold
1684                        case 0x35:
1685                            // By default, text is not bold.
1686                            switch ($operand) {
1687                                case false:
1688                                case true:
1689                                    $oStylePrl->styleFont['bold'] = $operand;
1690
1691                                    break;
1692                                case self::SPRA_VALUE:
1693                                    $oStylePrl->styleFont['bold'] = false;
1694
1695                                    break;
1696                                case self::SPRA_VALUE_OPPOSITE:
1697                                    $oStylePrl->styleFont['bold'] = true;
1698
1699                                    break;
1700                            }
1701
1702                            break;
1703                            // sprmCFStrike
1704                        case 0x37:
1705                            // By default, text is not struck through.
1706                            switch ($operand) {
1707                                case false:
1708                                case true:
1709                                    $oStylePrl->styleFont['strikethrough'] = $operand;
1710
1711                                    break;
1712                                case self::SPRA_VALUE:
1713                                    $oStylePrl->styleFont['strikethrough'] = false;
1714
1715                                    break;
1716                                case self::SPRA_VALUE_OPPOSITE:
1717                                    $oStylePrl->styleFont['strikethrough'] = true;
1718
1719                                    break;
1720                            }
1721
1722                            break;
1723                            // sprmCKul
1724                        case 0x3E:
1725                            switch (dechex($operand)) {
1726                                case 0x00:
1727                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_NONE;
1728
1729                                    break;
1730                                case 0x01:
1731                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_SINGLE;
1732
1733                                    break;
1734                                case 0x02:
1735                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_WORDS;
1736
1737                                    break;
1738                                case 0x03:
1739                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_DOUBLE;
1740
1741                                    break;
1742                                case 0x04:
1743                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_DOTTED;
1744
1745                                    break;
1746                                case 0x06:
1747                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_HEAVY;
1748
1749                                    break;
1750                                case 0x07:
1751                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_DASH;
1752
1753                                    break;
1754                                case 0x09:
1755                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_DOTDASH;
1756
1757                                    break;
1758                                case 0x0A:
1759                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_DOTDOTDASH;
1760
1761                                    break;
1762                                case 0x0B:
1763                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_WAVY;
1764
1765                                    break;
1766                                case 0x14:
1767                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_DOTTEDHEAVY;
1768
1769                                    break;
1770                                case 0x17:
1771                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_DASHHEAVY;
1772
1773                                    break;
1774                                case 0x19:
1775                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_DOTDASHHEAVY;
1776
1777                                    break;
1778                                case 0x1A:
1779                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_DOTDOTDASHHEAVY;
1780
1781                                    break;
1782                                case 0x1B:
1783                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_WAVYHEAVY;
1784
1785                                    break;
1786                                case 0x27:
1787                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_DASHLONG;
1788
1789                                    break;
1790                                case 0x2B:
1791                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_WAVYDOUBLE;
1792
1793                                    break;
1794                                case 0x37:
1795                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_DASHLONGHEAVY;
1796
1797                                    break;
1798                                default:
1799                                    $oStylePrl->styleFont['underline'] = Style\Font::UNDERLINE_NONE;
1800
1801                                    break;
1802                            }
1803
1804                            break;
1805                            // sprmCIco
1806                            //@see  http://msdn.microsoft.com/en-us/library/dd773060%28v=office.12%29.aspx
1807                        case 0x42:
1808                            switch (dechex($operand)) {
1809                                case 0x00:
1810                                case 0x01:
1811                                    $oStylePrl->styleFont['color'] = '000000';
1812
1813                                    break;
1814                                case 0x02:
1815                                    $oStylePrl->styleFont['color'] = '0000FF';
1816
1817                                    break;
1818                                case 0x03:
1819                                    $oStylePrl->styleFont['color'] = '00FFFF';
1820
1821                                    break;
1822                                case 0x04:
1823                                    $oStylePrl->styleFont['color'] = '00FF00';
1824
1825                                    break;
1826                                case 0x05:
1827                                    $oStylePrl->styleFont['color'] = 'FF00FF';
1828
1829                                    break;
1830                                case 0x06:
1831                                    $oStylePrl->styleFont['color'] = 'FF0000';
1832
1833                                    break;
1834                                case 0x07:
1835                                    $oStylePrl->styleFont['color'] = 'FFFF00';
1836
1837                                    break;
1838                                case 0x08:
1839                                    $oStylePrl->styleFont['color'] = 'FFFFFF';
1840
1841                                    break;
1842                                case 0x09:
1843                                    $oStylePrl->styleFont['color'] = '000080';
1844
1845                                    break;
1846                                case 0x0A:
1847                                    $oStylePrl->styleFont['color'] = '008080';
1848
1849                                    break;
1850                                case 0x0B:
1851                                    $oStylePrl->styleFont['color'] = '008000';
1852
1853                                    break;
1854                                case 0x0C:
1855                                    $oStylePrl->styleFont['color'] = '800080';
1856
1857                                    break;
1858                                case 0x0D:
1859                                    $oStylePrl->styleFont['color'] = '800080';
1860
1861                                    break;
1862                                case 0x0E:
1863                                    $oStylePrl->styleFont['color'] = '808000';
1864
1865                                    break;
1866                                case 0x0F:
1867                                    $oStylePrl->styleFont['color'] = '808080';
1868
1869                                    break;
1870                                case 0x10:
1871                                    $oStylePrl->styleFont['color'] = 'C0C0C0';
1872                            }
1873
1874                            break;
1875                            // sprmCHps
1876                        case 0x43:
1877                            $oStylePrl->styleFont['size'] = $operand / 2;
1878
1879                            break;
1880                            // sprmCIss
1881                        case 0x48:
1882                            if (!isset($oStylePrl->styleFont['superScript'])) {
1883                                $oStylePrl->styleFont['superScript'] = false;
1884                            }
1885                            if (!isset($oStylePrl->styleFont['subScript'])) {
1886                                $oStylePrl->styleFont['subScript'] = false;
1887                            }
1888                            switch (dechex($operand)) {
1889                                case 0x00:
1890                                    // Normal text
1891                                    break;
1892                                case 0x01:
1893                                    $oStylePrl->styleFont['superScript'] = true;
1894
1895                                    break;
1896                                case 0x02:
1897                                    $oStylePrl->styleFont['subScript'] = true;
1898
1899                                    break;
1900                            }
1901
1902                            break;
1903                            // sprmCRgFtc0
1904                        case 0x4F:
1905                            $oStylePrl->styleFont['name'] = '';
1906                            if (isset($this->arrayFonts[$operand])) {
1907                                $oStylePrl->styleFont['name'] = $this->arrayFonts[$operand]['main'];
1908                            }
1909
1910                            break;
1911                            // sprmCRgFtc1
1912                        case 0x50:
1913                            // if the language for the text is an East Asian language
1914                            break;
1915                            // sprmCRgFtc2
1916                        case 0x51:
1917                            // if the character falls outside the Unicode character range
1918                            break;
1919                            // sprmCFSpec
1920                        case 0x55:
1921                            //$sprmCFSpec = $operand;
1922                            break;
1923                            // sprmCFtcBi
1924                        case 0x5E:
1925                            break;
1926                            // sprmCFItalicBi
1927                        case 0x5D:
1928                            break;
1929                            // sprmCHpsBi
1930                        case 0x61:
1931                            break;
1932                            // sprmCShd80
1933                            //@see  http://msdn.microsoft.com/en-us/library/dd923447%28v=office.12%29.aspx
1934                        case 0x66:
1935                            // $operand = self::getInt2d($data, $pos);
1936                            $pos += 2;
1937                            $cbNum -= 2;
1938
1939                            // $ipat = ($operand >> 0) && bindec('111111');
1940                            // $icoBack = ($operand >> 6) && bindec('11111');
1941                            // $icoFore = ($operand >> 11) && bindec('11111');
1942                            break;
1943                            // sprmCCv
1944                            //@see  http://msdn.microsoft.com/en-us/library/dd952824%28v=office.12%29.aspx
1945                        case 0x70:
1946                            $red = str_pad(dechex(self::getInt1d($this->dataWorkDocument, $pos)), 2, '0', STR_PAD_LEFT);
1947                            ++$pos;
1948                            $green = str_pad(dechex(self::getInt1d($this->dataWorkDocument, $pos)), 2, '0', STR_PAD_LEFT);
1949                            ++$pos;
1950                            $blue = str_pad(dechex(self::getInt1d($this->dataWorkDocument, $pos)), 2, '0', STR_PAD_LEFT);
1951                            ++$pos;
1952                            ++$pos;
1953                            $oStylePrl->styleFont['color'] = $red . $green . $blue;
1954                            $cbNum -= 4;
1955
1956                            break;
1957                        default:
1958                            // print_r('@todo Character : 0x'.dechex($oSprm->isPmd));
1959                            // print_r(PHP_EOL);
1960                    }
1961
1962                    break;
1963                    // Picture property
1964                case 0x03:
1965                    break;
1966                    // Section property
1967                case 0x04:
1968                    if (!isset($oStylePrl->styleSection)) {
1969                        $oStylePrl->styleSection = [];
1970                    }
1971                    switch ($oSprm->isPmd) {
1972                        // sprmSNfcPgn
1973                        case 0x0E:
1974                            // numbering format used for page numbers
1975                            break;
1976                            // sprmSXaPage
1977                        case 0x1F:
1978                            $oStylePrl->styleSection['pageSizeW'] = $operand;
1979
1980                            break;
1981                            // sprmSYaPage
1982                        case 0x20:
1983                            $oStylePrl->styleSection['pageSizeH'] = $operand;
1984
1985                            break;
1986                            // sprmSDxaLeft
1987                        case 0x21:
1988                            $oStylePrl->styleSection['marginLeft'] = $operand;
1989
1990                            break;
1991                            // sprmSDxaRight
1992                        case 0x22:
1993                            $oStylePrl->styleSection['marginRight'] = $operand;
1994
1995                            break;
1996                            // sprmSDyaTop
1997                        case 0x23:
1998                            $oStylePrl->styleSection['marginTop'] = $operand;
1999
2000                            break;
2001                            // sprmSDyaBottom
2002                        case 0x24:
2003                            $oStylePrl->styleSection['marginBottom'] = $operand;
2004
2005                            break;
2006                            // sprmSFBiDi
2007                        case 0x28:
2008                            // RTL layout
2009                            break;
2010                            // sprmSDxtCharSpace
2011                        case 0x30:
2012                            // characpter pitch
2013                            break;
2014                            // sprmSDyaLinePitch
2015                        case 0x31:
2016                            // line height
2017                            break;
2018                            // sprmSClm
2019                        case 0x32:
2020                            // document grid mode
2021                            break;
2022                            // sprmSTextFlow
2023                        case 0x33:
2024                            // text flow
2025                            break;
2026                        default:
2027                            // print_r('@todo Section : 0x'.dechex($oSprm->isPmd));
2028                            // print_r(PHP_EOL);
2029                    }
2030
2031                    break;
2032                    // Table property
2033                case 0x05:
2034                    break;
2035            }
2036        } while ($cbNum > 0);
2037
2038        if (null !== $sprmCPicLocation) {
2039            if (null !== $sprmCFData && $sprmCFData == 0x01) {
2040                // NilPICFAndBinData
2041                //@todo Read Hyperlink structure
2042                /*$lcb = self::getInt4d($this->dataData, $sprmCPicLocation);
2043                $sprmCPicLocation += 4;
2044                $cbHeader = self::getInt2d($this->dataData, $sprmCPicLocation);
2045                $sprmCPicLocation += 2;
2046                // ignored
2047                $sprmCPicLocation += 62;
2048                // depending of the element
2049                // Hyperlink => HFD
2050                // HFD > bits
2051                $sprmCPicLocation += 1;
2052                // HFD > clsid
2053                $sprmCPicLocation += 16;
2054                // HFD > hyperlink
2055                //@see  http://msdn.microsoft.com/en-us/library/dd909835%28v=office.12%29.aspx
2056                $streamVersion = self::getInt4d($this->dataData, $sprmCPicLocation);
2057                $sprmCPicLocation += 4;
2058                $data = self::getInt4d($this->dataData, $sprmCPicLocation);
2059                $sprmCPicLocation += 4;
2060                $hlstmfAbsFromGetdataRel = ($data >> 9) & bindec('1');
2061                $hlstmfMonikerSavedAsStr = ($data >> 8) & bindec('1');
2062                $hlstmfHasFrameName = ($data >> 7) & bindec('1');
2063                $hlstmfHasCreationTime = ($data >> 6) & bindec('1');
2064                $hlstmfHasGUID = ($data >> 5) & bindec('1');
2065                $hlstmfHasDisplayName = ($data >> 4) & bindec('1');
2066                $hlstmfHasLocationStr = ($data >> 3) & bindec('1');
2067                $hlstmfSiteGaveDisplayName = ($data >> 2) & bindec('1');
2068                $hlstmfIsAbsolute = ($data >> 1) & bindec('1');
2069                $hlstmfHasMoniker = ($data >> 0) & bindec('1');
2070                for ($inc = 0; $inc <= 32; $inc++) {
2071                    echo ($data >> $inc) & bindec('1');
2072                }
2073
2074                print_r('$hlstmfHasMoniker > '.$hlstmfHasMoniker.PHP_EOL);
2075                print_r('$hlstmfIsAbsolute > '.$hlstmfIsAbsolute.PHP_EOL);
2076                print_r('$hlstmfSiteGaveDisplayName > '.$hlstmfSiteGaveDisplayName.PHP_EOL);
2077                print_r('$hlstmfHasLocationStr > '.$hlstmfHasLocationStr.PHP_EOL);
2078                print_r('$hlstmfHasDisplayName > '.$hlstmfHasDisplayName.PHP_EOL);
2079                print_r('$hlstmfHasGUID > '.$hlstmfHasGUID.PHP_EOL);
2080                print_r('$hlstmfHasCreationTime > '.$hlstmfHasCreationTime.PHP_EOL);
2081                print_r('$hlstmfHasFrameName > '.$hlstmfHasFrameName.PHP_EOL);
2082                print_r('$hlstmfMonikerSavedAsStr > '.$hlstmfMonikerSavedAsStr.PHP_EOL);
2083                print_r('$hlstmfAbsFromGetdataRel > '.$hlstmfAbsFromGetdataRel.PHP_EOL);
2084                if ($streamVersion == 2) {
2085                    $AAA = self::getInt4d($this->dataData, $sprmCPicLocation);
2086                    echo 'AAAA : '.$AAA.PHP_EOL;
2087                    if ($hlstmfHasDisplayName == 1) {
2088                        echo 'displayName'.PHP_EOL;
2089                    }
2090                    if ($hlstmfHasFrameName == 1) {
2091                        echo 'targetFrameName'.PHP_EOL;
2092                    }
2093                    if ($hlstmfHasMoniker == 1 || $hlstmfMonikerSavedAsStr == 1) {
2094                        $sprmCPicLocation += 16;
2095                        $length = self::getInt4d($this->dataData, $sprmCPicLocation);
2096                        $sprmCPicLocation += 4;
2097                        for ($inc = 0; $inc < ($length / 2); $inc++) {
2098                            $chr = self::getInt2d($this->dataData, $sprmCPicLocation);
2099                            $sprmCPicLocation += 2;
2100                            print_r(chr($chr));
2101                        }
2102                        echo PHP_EOL;
2103                        echo 'moniker : '.$length.PHP_EOL;
2104                    }
2105                    if ($hlstmfHasMoniker == 1 || $hlstmfMonikerSavedAsStr == 1) {
2106                        echo 'oleMoniker'.PHP_EOL;
2107                    }
2108                    if ($hlstmfHasLocationStr == 1) {
2109                        echo 'location'.PHP_EOL;
2110                    }
2111                    if ($hlstmfHasGUID == 1) {
2112                        echo 'guid'.PHP_EOL;
2113                        $sprmCPicLocation += 16;
2114                    }
2115                    if ($hlstmfHasCreationTime == 1) {
2116                        echo 'fileTime'.PHP_EOL;
2117                        $sprmCPicLocation += 4;
2118                    }
2119                    echo 'HYPERLINK'.PHP_EOL;
2120                }*/
2121            } else {
2122                // Pictures
2123                //@see  http://msdn.microsoft.com/en-us/library/dd925458%28v=office.12%29.aspx
2124                //@see  http://msdn.microsoft.com/en-us/library/dd926136%28v=office.12%29.aspx
2125                // PICF : lcb
2126                $sprmCPicLocation += 4;
2127                // PICF : cbHeader
2128                $sprmCPicLocation += 2;
2129                // PICF : mfpf : mm
2130                $mfpfMm = self::getInt2d($this->dataData, $sprmCPicLocation);
2131                $sprmCPicLocation += 2;
2132                // PICF : mfpf : xExt
2133                $sprmCPicLocation += 2;
2134                // PICF : mfpf : yExt
2135                $sprmCPicLocation += 2;
2136                // PICF : mfpf : swHMF
2137                $sprmCPicLocation += 2;
2138                // PICF : innerHeader : grf
2139                $sprmCPicLocation += 4;
2140                // PICF : innerHeader : padding1
2141                $sprmCPicLocation += 4;
2142                // PICF : innerHeader : mmPM
2143                $sprmCPicLocation += 2;
2144                // PICF : innerHeader : padding2
2145                $sprmCPicLocation += 4;
2146                // PICF : picmid : dxaGoal
2147                $picmidDxaGoal = self::getInt2d($this->dataData, $sprmCPicLocation);
2148                $sprmCPicLocation += 2;
2149                // PICF : picmid : dyaGoal
2150                $picmidDyaGoal = self::getInt2d($this->dataData, $sprmCPicLocation);
2151                $sprmCPicLocation += 2;
2152                // PICF : picmid : mx
2153                $picmidMx = self::getInt2d($this->dataData, $sprmCPicLocation);
2154                $sprmCPicLocation += 2;
2155                // PICF : picmid : my
2156                $picmidMy = self::getInt2d($this->dataData, $sprmCPicLocation);
2157                $sprmCPicLocation += 2;
2158                // PICF : picmid : dxaReserved1
2159                $picmidDxaCropLeft = self::getInt2d($this->dataData, $sprmCPicLocation);
2160                $sprmCPicLocation += 2;
2161                // PICF : picmid : dyaReserved1
2162                $picmidDxaCropTop = self::getInt2d($this->dataData, $sprmCPicLocation);
2163                $sprmCPicLocation += 2;
2164                // PICF : picmid : dxaReserved2
2165                $picmidDxaCropRight = self::getInt2d($this->dataData, $sprmCPicLocation);
2166                $sprmCPicLocation += 2;
2167                // PICF : picmid : dyaReserved2
2168                $picmidDxaCropBottom = self::getInt2d($this->dataData, $sprmCPicLocation);
2169                $sprmCPicLocation += 2;
2170                // PICF : picmid : fReserved
2171                ++$sprmCPicLocation;
2172                // PICF : picmid : bpp
2173                ++$sprmCPicLocation;
2174                // PICF : picmid : brcTop80
2175                $sprmCPicLocation += 4;
2176                // PICF : picmid : brcLeft80
2177                $sprmCPicLocation += 4;
2178                // PICF : picmid : brcBottom80
2179                $sprmCPicLocation += 4;
2180                // PICF : picmid : brcRight80
2181                $sprmCPicLocation += 4;
2182                // PICF : picmid : dxaReserved3
2183                $sprmCPicLocation += 2;
2184                // PICF : picmid : dyaReserved3
2185                $sprmCPicLocation += 2;
2186                // PICF : cProps
2187                $sprmCPicLocation += 2;
2188
2189                if ($mfpfMm == 0x0066) {
2190                    // cchPicName
2191                    $cchPicName = self::getInt1d($this->dataData, $sprmCPicLocation);
2192                    ++$sprmCPicLocation;
2193
2194                    // stPicName
2195                    //$stPicName = '';
2196                    for ($inc = 0; $inc <= $cchPicName; ++$inc) {
2197                        //$chr = self::getInt1d($this->dataData, $sprmCPicLocation);
2198                        ++$sprmCPicLocation;
2199                        //$stPicName .= chr($chr);
2200                    }
2201                }
2202
2203                // picture (OfficeArtInlineSpContainer)
2204                // picture : shape
2205                $shapeRH = $this->loadRecordHeader($this->dataData, $sprmCPicLocation);
2206                $sprmCPicLocation += 8;
2207                if ($shapeRH['recVer'] == 0xF && $shapeRH['recInstance'] == 0x000 && $shapeRH['recType'] == 0xF004) {
2208                    $sprmCPicLocation += $shapeRH['recLen'];
2209                }
2210                // picture : rgfb
2211                //@see  http://msdn.microsoft.com/en-us/library/dd950560%28v=office.12%29.aspx
2212                $fileBlockRH = $this->loadRecordHeader($this->dataData, $sprmCPicLocation);
2213                while ($fileBlockRH['recType'] == 0xF007 || ($fileBlockRH['recType'] >= 0xF018 && $fileBlockRH['recType'] <= 0xF117)) {
2214                    $sprmCPicLocation += 8;
2215                    switch ($fileBlockRH['recType']) {
2216                        // OfficeArtFBSE
2217                        //@see  http://msdn.microsoft.com/en-us/library/dd944923%28v=office.12%29.aspx
2218                        case 0xF007:
2219                            // btWin32
2220                            ++$sprmCPicLocation;
2221                            // btMacOS
2222                            ++$sprmCPicLocation;
2223                            // rgbUid
2224                            $sprmCPicLocation += 16;
2225                            // tag
2226                            $sprmCPicLocation += 2;
2227                            // size
2228                            $sprmCPicLocation += 4;
2229                            // cRef
2230                            $sprmCPicLocation += 4;
2231                            // foDelay
2232                            $sprmCPicLocation += 4;
2233                            // unused1
2234                            ++$sprmCPicLocation;
2235                            // cbName
2236                            $cbName = self::getInt1d($this->dataData, $sprmCPicLocation);
2237                            ++$sprmCPicLocation;
2238                            // unused2
2239                            ++$sprmCPicLocation;
2240                            // unused3
2241                            ++$sprmCPicLocation;
2242                            // nameData
2243                            if ($cbName > 0) {
2244                                //$nameData = '';
2245                                for ($inc = 0; $inc <= ($cbName / 2); ++$inc) {
2246                                    //$chr = self::getInt2d($this->dataData, $sprmCPicLocation);
2247                                    $sprmCPicLocation += 2;
2248                                    //$nameData .= chr($chr);
2249                                }
2250                            }
2251                            // embeddedBlip
2252                            //@see  http://msdn.microsoft.com/en-us/library/dd910081%28v=office.12%29.aspx
2253                            $embeddedBlipRH = $this->loadRecordHeader($this->dataData, $sprmCPicLocation);
2254                            switch ($embeddedBlipRH['recType']) {
2255                                case self::OFFICEARTBLIPJPG:
2256                                case self::OFFICEARTBLIPJPEG:
2257                                    if (!isset($oStylePrl->image)) {
2258                                        $oStylePrl->image = [];
2259                                    }
2260                                    $sprmCPicLocation += 8;
2261                                    // embeddedBlip : rgbUid1
2262                                    $sprmCPicLocation += 16;
2263                                    if ($embeddedBlipRH['recInstance'] == 0x6E1) {
2264                                        // rgbUid2
2265                                        $sprmCPicLocation += 16;
2266                                    }
2267                                    // embeddedBlip : tag
2268                                    ++$sprmCPicLocation;
2269                                    // embeddedBlip : BLIPFileData
2270                                    $oStylePrl->image['data'] = substr($this->dataData, $sprmCPicLocation, $embeddedBlipRH['recLen']);
2271                                    $oStylePrl->image['format'] = 'jpg';
2272                                    // Image Size
2273                                    $iCropWidth = $picmidDxaGoal - ($picmidDxaCropLeft + $picmidDxaCropRight);
2274                                    $iCropHeight = $picmidDyaGoal - ($picmidDxaCropTop + $picmidDxaCropBottom);
2275                                    if (!$iCropWidth) {
2276                                        $iCropWidth = 1;
2277                                    }
2278                                    if (!$iCropHeight) {
2279                                        $iCropHeight = 1;
2280                                    }
2281                                    $oStylePrl->image['width'] = Drawing::twipsToPixels($iCropWidth * $picmidMx / 1000);
2282                                    $oStylePrl->image['height'] = Drawing::twipsToPixels($iCropHeight * $picmidMy / 1000);
2283
2284                                    $sprmCPicLocation += $embeddedBlipRH['recLen'];
2285
2286                                    break;
2287                                case self::OFFICEARTBLIPPNG:
2288                                    break;
2289                                default:
2290                                    // print_r(dechex($embeddedBlipRH['recType']));
2291                            }
2292
2293                            break;
2294                    }
2295                    $fileBlockRH = $this->loadRecordHeader($this->dataData, $sprmCPicLocation);
2296                }
2297            }
2298        }
2299
2300        $oStylePrl->length = $pos - $posStart;
2301
2302        return $oStylePrl;
2303    }
2304
2305    /**
2306     * Read a record header.
2307     *
2308     * @param string $stream
2309     * @param int $pos
2310     *
2311     * @return array
2312     */
2313    private function loadRecordHeader($stream, $pos)
2314    {
2315        $rec = self::getInt2d($stream, $pos);
2316        $recType = self::getInt2d($stream, $pos + 2);
2317        $recLen = self::getInt4d($stream, $pos + 4);
2318
2319        return [
2320            'recVer' => ($rec >> 0) & bindec('1111'),
2321            'recInstance' => ($rec >> 4) & bindec('111111111111'),
2322            'recType' => $recType,
2323            'recLen' => $recLen,
2324        ];
2325    }
2326
2327    private function generatePhpWord(): void
2328    {
2329        foreach ($this->arraySections as $itmSection) {
2330            $oSection = $this->phpWord->addSection();
2331            $oSection->setStyle($itmSection->styleSection);
2332
2333            $sHYPERLINK = '';
2334            foreach ($this->arrayParagraphs as $itmParagraph) {
2335                $textPara = $itmParagraph;
2336                foreach ($this->arrayCharacters as $oCharacters) {
2337                    $subText = mb_substr($textPara, $oCharacters->pos_start, $oCharacters->pos_len);
2338                    $subText = str_replace(chr(13), PHP_EOL, $subText);
2339                    $arrayText = explode(PHP_EOL, $subText);
2340                    if (end($arrayText) == '') {
2341                        array_pop($arrayText);
2342                    }
2343                    if (reset($arrayText) == '') {
2344                        array_shift($arrayText);
2345                    }
2346
2347                    // Style Character
2348                    $styleFont = [];
2349                    if (isset($oCharacters->style)) {
2350                        if (isset($oCharacters->style->styleFont)) {
2351                            $styleFont = $oCharacters->style->styleFont;
2352                        }
2353                    }
2354
2355                    foreach ($arrayText as $sText) {
2356                        // HyperLink
2357                        if (empty($sText) && !empty($sHYPERLINK)) {
2358                            $arrHYPERLINK = explode('"', $sHYPERLINK);
2359                            $oSection->addLink($arrHYPERLINK[1], null);
2360                            // print_r('>addHyperLink<'.$sHYPERLINK.'>'.ord($sHYPERLINK[0]).EOL);
2361                            $sHYPERLINK = '';
2362                        }
2363
2364                        // TextBreak
2365                        if (empty($sText)) {
2366                            $oSection->addTextBreak();
2367                            $sHYPERLINK = '';
2368                            // print_r('>addTextBreak<' . EOL);
2369                        }
2370
2371                        if (!empty($sText)) {
2372                            if (!empty($sHYPERLINK) && ord($sText[0]) > 20) {
2373                                $sHYPERLINK .= $sText;
2374                            }
2375                            if (empty($sHYPERLINK)) {
2376                                if (ord($sText[0]) > 20) {
2377                                    if (strpos(trim($sText), 'HYPERLINK "') === 0) {
2378                                        $sHYPERLINK = $sText;
2379                                    } else {
2380                                        $oSection->addText($sText, $styleFont);
2381                                        // print_r('>addText<'.$sText.'>'.ord($sText[0]).EOL);
2382                                    }
2383                                }
2384                                if (ord($sText[0]) == 1) {
2385                                    if (isset($oCharacters->style->image)) {
2386                                        $fileImage = tempnam(sys_get_temp_dir(), 'PHPWord_MsDoc') . '.' . $oCharacters->style->image['format'];
2387                                        file_put_contents($fileImage, $oCharacters->style->image['data']);
2388                                        $oSection->addImage($fileImage, ['width' => $oCharacters->style->image['width'], 'height' => $oCharacters->style->image['height']]);
2389                                        // print_r('>addImage<'.$fileImage.'>'.EOL);
2390                                    }
2391                                }
2392                            }
2393                        }
2394                    }
2395                }
2396            }
2397        }
2398    }
2399
2400    /**
2401     * Read 8-bit unsigned integer.
2402     *
2403     * @param string $data
2404     * @param int $pos
2405     *
2406     * @return int
2407     */
2408    public static function getInt1d($data, $pos)
2409    {
2410        return ord($data[$pos]);
2411    }
2412
2413    /**
2414     * Read 16-bit unsigned integer.
2415     *
2416     * @param string $data
2417     * @param int $pos
2418     *
2419     * @return int
2420     */
2421    public static function getInt2d($data, $pos)
2422    {
2423        return ord($data[$pos]) | (ord($data[$pos + 1]) << 8);
2424    }
2425
2426    /**
2427     * Read 24-bit signed integer.
2428     *
2429     * @param string $data
2430     * @param int $pos
2431     *
2432     * @return int
2433     */
2434    public static function getInt3d($data, $pos)
2435    {
2436        return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16);
2437    }
2438
2439    /**
2440     * Read 32-bit signed integer.
2441     *
2442     * @param string $data
2443     * @param int $pos
2444     *
2445     * @return int
2446     */
2447    public static function getInt4d($data, $pos)
2448    {
2449        // FIX: represent numbers correctly on 64-bit system
2450        // http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334
2451        // Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems
2452        $or24 = ord($data[$pos + 3]);
2453        if ($or24 >= 128) {
2454            // negative number
2455            $ord24 = -abs((256 - $or24) << 24);
2456        } else {
2457            $ord24 = ($or24 & 127) << 24;
2458        }
2459
2460        return ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $ord24;
2461    }
2462}