source: sourcecode/application/libraries/PHPExcel/Writer/Excel5/Escher.php @ 1

Last change on this file since 1 was 1, checked in by dungnv, 11 years ago
File size: 13.2 KB
Line 
1<?php
2/**
3 * PHPExcel
4 *
5 * Copyright (c) 2006 - 2014 PHPExcel
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20 *
21 * @category   PHPExcel
22 * @package    PHPExcel_Writer_Excel5
23 * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
24 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
25 * @version    1.8.0, 2014-03-02
26 */
27
28
29/**
30 * PHPExcel_Shared_Escher_DggContainer_BstoreContainer
31 *
32 * @category   PHPExcel
33 * @package    PHPExcel_Writer_Excel5
34 * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)
35 */
36class PHPExcel_Writer_Excel5_Escher
37{
38        /**
39         * The object we are writing
40         */
41        private $_object;
42
43        /**
44         * The written binary data
45         */
46        private $_data;
47
48        /**
49         * Shape offsets. Positions in binary stream where a new shape record begins
50         *
51         * @var array
52         */
53        private $_spOffsets;
54
55        /**
56         * Shape types.
57         *
58         * @var array
59         */
60        private $_spTypes;
61       
62        /**
63         * Constructor
64         *
65         * @param mixed
66         */
67        public function __construct($object)
68        {
69                $this->_object = $object;
70        }
71
72        /**
73         * Process the object to be written
74         */
75        public function close()
76        {
77                // initialize
78                $this->_data = '';
79
80                switch (get_class($this->_object)) {
81
82                case 'PHPExcel_Shared_Escher':
83                        if ($dggContainer = $this->_object->getDggContainer()) {
84                                $writer = new PHPExcel_Writer_Excel5_Escher($dggContainer);
85                                $this->_data = $writer->close();
86                        } else if ($dgContainer = $this->_object->getDgContainer()) {
87                                $writer = new PHPExcel_Writer_Excel5_Escher($dgContainer);
88                                $this->_data = $writer->close();
89                                $this->_spOffsets = $writer->getSpOffsets();
90                                $this->_spTypes = $writer->getSpTypes();
91                        }
92                        break;
93
94                case 'PHPExcel_Shared_Escher_DggContainer':
95                        // this is a container record
96
97                        // initialize
98                        $innerData = '';
99
100                        // write the dgg
101                        $recVer                 = 0x0;
102                        $recInstance    = 0x0000;
103                        $recType                = 0xF006;
104
105                        $recVerInstance  = $recVer;
106                        $recVerInstance |= $recInstance << 4;
107
108                        // dgg data
109                        $dggData =
110                                pack('VVVV'
111                                        , $this->_object->getSpIdMax() // maximum shape identifier increased by one
112                                        , $this->_object->getCDgSaved() + 1 // number of file identifier clusters increased by one
113                                        , $this->_object->getCSpSaved()
114                                        , $this->_object->getCDgSaved() // count total number of drawings saved
115                                );
116
117                        // add file identifier clusters (one per drawing)
118                        $IDCLs = $this->_object->getIDCLs();
119
120                        foreach ($IDCLs as $dgId => $maxReducedSpId) {
121                                $dggData .= pack('VV', $dgId, $maxReducedSpId + 1);
122                        }
123
124                        $header = pack('vvV', $recVerInstance, $recType, strlen($dggData));
125                        $innerData .= $header . $dggData;
126
127                        // write the bstoreContainer
128                        if ($bstoreContainer = $this->_object->getBstoreContainer()) {
129                                $writer = new PHPExcel_Writer_Excel5_Escher($bstoreContainer);
130                                $innerData .= $writer->close();
131                        }
132
133                        // write the record
134                        $recVer                 = 0xF;
135                        $recInstance    = 0x0000;
136                        $recType                = 0xF000;
137                        $length                 = strlen($innerData);
138
139                        $recVerInstance  = $recVer;
140                        $recVerInstance |= $recInstance << 4;
141
142                        $header = pack('vvV', $recVerInstance, $recType, $length);
143
144                        $this->_data = $header . $innerData;
145                        break;
146
147                case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer':
148                        // this is a container record
149
150                        // initialize
151                        $innerData = '';
152
153                        // treat the inner data
154                        if ($BSECollection = $this->_object->getBSECollection()) {
155                                foreach ($BSECollection as $BSE) {
156                                        $writer = new PHPExcel_Writer_Excel5_Escher($BSE);
157                                        $innerData .= $writer->close();
158                                }
159                        }
160
161                        // write the record
162                        $recVer                 = 0xF;
163                        $recInstance    = count($this->_object->getBSECollection());
164                        $recType                = 0xF001;
165                        $length                 = strlen($innerData);
166
167                        $recVerInstance  = $recVer;
168                        $recVerInstance |= $recInstance << 4;
169
170                        $header = pack('vvV', $recVerInstance, $recType, $length);
171
172                        $this->_data = $header . $innerData;
173                        break;
174
175                case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE':
176                        // this is a semi-container record
177
178                        // initialize
179                        $innerData = '';
180
181                        // here we treat the inner data
182                        if ($blip = $this->_object->getBlip()) {
183                                $writer = new PHPExcel_Writer_Excel5_Escher($blip);
184                                $innerData .= $writer->close();
185                        }
186
187                        // initialize
188                        $data = '';
189
190                        $btWin32 = $this->_object->getBlipType();
191                        $btMacOS = $this->_object->getBlipType();
192                        $data .= pack('CC', $btWin32, $btMacOS);
193
194                        $rgbUid = pack('VVVV', 0,0,0,0); // todo
195                        $data .= $rgbUid;
196
197                        $tag = 0;
198                        $size = strlen($innerData);
199                        $cRef = 1;
200                        $foDelay = 0; //todo
201                        $unused1 = 0x0;
202                        $cbName = 0x0;
203                        $unused2 = 0x0;
204                        $unused3 = 0x0;
205                        $data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3);
206
207                        $data .= $innerData;
208
209                        // write the record
210                        $recVer                 = 0x2;
211                        $recInstance    = $this->_object->getBlipType();
212                        $recType                = 0xF007;
213                        $length                 = strlen($data);
214
215                        $recVerInstance  = $recVer;
216                        $recVerInstance |=      $recInstance << 4;
217
218                        $header = pack('vvV', $recVerInstance, $recType, $length);
219
220                        $this->_data = $header;
221
222                        $this->_data .= $data;
223                        break;
224
225                case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip':
226                        // this is an atom record
227
228                        // write the record
229                        switch ($this->_object->getParent()->getBlipType()) {
230
231                        case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG:
232                                // initialize
233                                $innerData = '';
234
235                                $rgbUid1 = pack('VVVV', 0,0,0,0); // todo
236                                $innerData .= $rgbUid1;
237
238                                $tag = 0xFF; // todo
239                                $innerData .= pack('C', $tag);
240
241                                $innerData .= $this->_object->getData();
242
243                                $recVer                 = 0x0;
244                                $recInstance    = 0x46A;
245                                $recType                = 0xF01D;
246                                $length                 = strlen($innerData);
247
248                                $recVerInstance  = $recVer;
249                                $recVerInstance |=      $recInstance << 4;
250
251                                $header = pack('vvV', $recVerInstance, $recType, $length);
252
253                                $this->_data = $header;
254
255                                $this->_data .= $innerData;
256                                break;
257
258                        case PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG:
259                                // initialize
260                                $innerData = '';
261
262                                $rgbUid1 = pack('VVVV', 0,0,0,0); // todo
263                                $innerData .= $rgbUid1;
264
265                                $tag = 0xFF; // todo
266                                $innerData .= pack('C', $tag);
267
268                                $innerData .= $this->_object->getData();
269
270                                $recVer                 = 0x0;
271                                $recInstance    = 0x6E0;
272                                $recType                = 0xF01E;
273                                $length                 = strlen($innerData);
274
275                                $recVerInstance  = $recVer;
276                                $recVerInstance |=      $recInstance << 4;
277
278                                $header = pack('vvV', $recVerInstance, $recType, $length);
279
280                                $this->_data = $header;
281
282                                $this->_data .= $innerData;
283                                break;
284
285                        }
286                        break;
287
288                case 'PHPExcel_Shared_Escher_DgContainer':
289                        // this is a container record
290
291                        // initialize
292                        $innerData = '';
293
294                        // write the dg
295                        $recVer                 = 0x0;
296                        $recInstance    = $this->_object->getDgId();
297                        $recType                = 0xF008;
298                        $length                 = 8;
299
300                        $recVerInstance  = $recVer;
301                        $recVerInstance |= $recInstance << 4;
302
303                        $header = pack('vvV', $recVerInstance, $recType, $length);
304
305                        // number of shapes in this drawing (including group shape)
306                        $countShapes = count($this->_object->getSpgrContainer()->getChildren());
307                        $innerData .= $header . pack('VV', $countShapes, $this->_object->getLastSpId());
308                        //$innerData .= $header . pack('VV', 0, 0);
309
310                        // write the spgrContainer
311                        if ($spgrContainer = $this->_object->getSpgrContainer()) {
312                                $writer = new PHPExcel_Writer_Excel5_Escher($spgrContainer);
313                                $innerData .= $writer->close();
314
315                                // get the shape offsets relative to the spgrContainer record
316                                $spOffsets = $writer->getSpOffsets();
317                                $spTypes   = $writer->getSpTypes();
318                               
319                                // save the shape offsets relative to dgContainer
320                                foreach ($spOffsets as & $spOffset) {
321                                        $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes)
322                                }
323
324                                $this->_spOffsets = $spOffsets;
325                                $this->_spTypes = $spTypes;
326                        }
327
328                        // write the record
329                        $recVer                 = 0xF;
330                        $recInstance    = 0x0000;
331                        $recType                = 0xF002;
332                        $length                 = strlen($innerData);
333
334                        $recVerInstance  = $recVer;
335                        $recVerInstance |= $recInstance << 4;
336
337                        $header = pack('vvV', $recVerInstance, $recType, $length);
338
339                        $this->_data = $header . $innerData;
340                        break;
341
342                case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer':
343                        // this is a container record
344
345                        // initialize
346                        $innerData = '';
347
348                        // initialize spape offsets
349                        $totalSize = 8;
350                        $spOffsets = array();
351                        $spTypes   = array();
352
353                        // treat the inner data
354                        foreach ($this->_object->getChildren() as $spContainer) {
355                                $writer = new PHPExcel_Writer_Excel5_Escher($spContainer);
356                                $spData = $writer->close();
357                                $innerData .= $spData;
358
359                                // save the shape offsets (where new shape records begin)
360                                $totalSize += strlen($spData);
361                                $spOffsets[] = $totalSize;
362                               
363                                $spTypes = array_merge($spTypes, $writer->getSpTypes());
364                        }
365
366                        // write the record
367                        $recVer                 = 0xF;
368                        $recInstance    = 0x0000;
369                        $recType                = 0xF003;
370                        $length                 = strlen($innerData);
371
372                        $recVerInstance  = $recVer;
373                        $recVerInstance |= $recInstance << 4;
374
375                        $header = pack('vvV', $recVerInstance, $recType, $length);
376
377                        $this->_data = $header . $innerData;
378                        $this->_spOffsets = $spOffsets;
379                        $this->_spTypes = $spTypes;
380                        break;
381
382                case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer':
383                        // initialize
384                        $data = '';
385
386                        // build the data
387
388                        // write group shape record, if necessary?
389                        if ($this->_object->getSpgr()) {
390                                $recVer                 = 0x1;
391                                $recInstance    = 0x0000;
392                                $recType                = 0xF009;
393                                $length                 = 0x00000010;
394
395                                $recVerInstance  = $recVer;
396                                $recVerInstance |= $recInstance << 4;
397
398                                $header = pack('vvV', $recVerInstance, $recType, $length);
399
400                                $data .= $header . pack('VVVV', 0,0,0,0);
401                        }
402                        $this->_spTypes[] = ($this->_object->getSpType());
403
404                        // write the shape record
405                        $recVer                 = 0x2;
406                        $recInstance    = $this->_object->getSpType(); // shape type
407                        $recType                = 0xF00A;
408                        $length                 = 0x00000008;
409
410                        $recVerInstance  = $recVer;
411                        $recVerInstance |= $recInstance << 4;
412
413                        $header = pack('vvV', $recVerInstance, $recType, $length);
414
415                        $data .= $header . pack('VV', $this->_object->getSpId(), $this->_object->getSpgr() ? 0x0005 : 0x0A00);
416
417
418                        // the options
419                        if ($this->_object->getOPTCollection()) {
420                                $optData = '';
421
422                                $recVer                 = 0x3;
423                                $recInstance    = count($this->_object->getOPTCollection());
424                                $recType                = 0xF00B;
425                                foreach ($this->_object->getOPTCollection() as $property => $value) {
426                                        $optData .= pack('vV', $property, $value);
427                                }
428                                $length                 = strlen($optData);
429
430                                $recVerInstance  = $recVer;
431                                $recVerInstance |= $recInstance << 4;
432
433                                $header = pack('vvV', $recVerInstance, $recType, $length);
434                                $data .= $header . $optData;
435                        }
436
437                        // the client anchor
438                        if ($this->_object->getStartCoordinates()) {
439                                $clientAnchorData = '';
440
441                                $recVer                 = 0x0;
442                                $recInstance    = 0x0;
443                                $recType                = 0xF010;
444
445                                // start coordinates
446                                list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getStartCoordinates());
447                                $c1 = PHPExcel_Cell::columnIndexFromString($column) - 1;
448                                $r1 = $row - 1;
449
450                                // start offsetX
451                                $startOffsetX = $this->_object->getStartOffsetX();
452
453                                // start offsetY
454                                $startOffsetY = $this->_object->getStartOffsetY();
455
456                                // end coordinates
457                                list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getEndCoordinates());
458                                $c2 = PHPExcel_Cell::columnIndexFromString($column) - 1;
459                                $r2 = $row - 1;
460
461                                // end offsetX
462                                $endOffsetX = $this->_object->getEndOffsetX();
463
464                                // end offsetY
465                                $endOffsetY = $this->_object->getEndOffsetY();
466
467                                $clientAnchorData = pack('vvvvvvvvv', $this->_object->getSpFlag(),
468                                        $c1, $startOffsetX, $r1, $startOffsetY,
469                                        $c2, $endOffsetX, $r2, $endOffsetY);
470                               
471                                $length                 = strlen($clientAnchorData);
472
473                                $recVerInstance  = $recVer;
474                                $recVerInstance |= $recInstance << 4;
475
476                                $header = pack('vvV', $recVerInstance, $recType, $length);
477                                $data .= $header . $clientAnchorData;
478                        }
479
480                        // the client data, just empty for now
481                        if (!$this->_object->getSpgr()) {
482                                $clientDataData = '';
483
484                                $recVer                 = 0x0;
485                                $recInstance    = 0x0;
486                                $recType                = 0xF011;
487
488                                $length = strlen($clientDataData);
489
490                                $recVerInstance  = $recVer;
491                                $recVerInstance |= $recInstance << 4;
492
493                                $header = pack('vvV', $recVerInstance, $recType, $length);
494                                $data .= $header . $clientDataData;
495                        }
496
497                        // write the record
498                        $recVer                 = 0xF;
499                        $recInstance    = 0x0000;
500                        $recType                = 0xF004;
501                        $length                 = strlen($data);
502
503                        $recVerInstance  = $recVer;
504                        $recVerInstance |= $recInstance << 4;
505
506                        $header = pack('vvV', $recVerInstance, $recType, $length);
507
508                        $this->_data = $header . $data;
509                        break;
510
511                }
512
513                return $this->_data;
514        }
515
516        /**
517         * Gets the shape offsets
518         *
519         * @return array
520         */
521        public function getSpOffsets()
522        {
523                return $this->_spOffsets;
524        }
525
526        /**
527         * Gets the shape types
528         *
529         * @return array
530         */
531        public function getSpTypes()
532        {
533                return $this->_spTypes;
534        }
535       
536       
537}
Note: See TracBrowser for help on using the repository browser.