1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
27:
28: 29: 30: 31: 32: 33: 34:
35: class PHPExcel_Reader_Excel5_Escher
36: {
37: const DGGCONTAINER = 0xF000;
38: const BSTORECONTAINER = 0xF001;
39: const DGCONTAINER = 0xF002;
40: const SPGRCONTAINER = 0xF003;
41: const SPCONTAINER = 0xF004;
42: const DGG = 0xF006;
43: const BSE = 0xF007;
44: const DG = 0xF008;
45: const SPGR = 0xF009;
46: const SP = 0xF00A;
47: const OPT = 0xF00B;
48: const CLIENTTEXTBOX = 0xF00D;
49: const CLIENTANCHOR = 0xF010;
50: const CLIENTDATA = 0xF011;
51: const BLIPJPEG = 0xF01D;
52: const BLIPPNG = 0xF01E;
53: const SPLITMENUCOLORS = 0xF11E;
54: const TERTIARYOPT = 0xF122;
55:
56: 57: 58: 59: 60:
61: private $_data;
62:
63: 64: 65: 66: 67:
68: private $_dataSize;
69:
70: 71: 72: 73: 74:
75: private $_pos;
76:
77: 78: 79: 80: 81:
82: private $_object;
83:
84: 85: 86: 87: 88:
89: public function __construct($object)
90: {
91: $this->_object = $object;
92: }
93:
94: 95: 96: 97: 98:
99: public function load($data)
100: {
101: $this->_data = $data;
102:
103:
104: $this->_dataSize = strlen($this->_data);
105:
106: $this->_pos = 0;
107:
108:
109: while ($this->_pos < $this->_dataSize) {
110:
111:
112: $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2);
113:
114: switch ($fbt) {
115: case self::DGGCONTAINER: $this->_readDggContainer(); break;
116: case self::DGG: $this->_readDgg(); break;
117: case self::BSTORECONTAINER: $this->_readBstoreContainer(); break;
118: case self::BSE: $this->_readBSE(); break;
119: case self::BLIPJPEG: $this->_readBlipJPEG(); break;
120: case self::BLIPPNG: $this->_readBlipPNG(); break;
121: case self::OPT: $this->_readOPT(); break;
122: case self::TERTIARYOPT: $this->_readTertiaryOPT(); break;
123: case self::SPLITMENUCOLORS: $this->_readSplitMenuColors(); break;
124: case self::DGCONTAINER: $this->_readDgContainer(); break;
125: case self::DG: $this->_readDg(); break;
126: case self::SPGRCONTAINER: $this->_readSpgrContainer(); break;
127: case self::SPCONTAINER: $this->_readSpContainer(); break;
128: case self::SPGR: $this->_readSpgr(); break;
129: case self::SP: $this->_readSp(); break;
130: case self::CLIENTTEXTBOX: $this->_readClientTextbox(); break;
131: case self::CLIENTANCHOR: $this->_readClientAnchor(); break;
132: case self::CLIENTDATA: $this->_readClientData(); break;
133: default: $this->_readDefault(); break;
134: }
135: }
136:
137: return $this->_object;
138: }
139:
140: 141: 142:
143: private function _readDefault()
144: {
145:
146: $verInstance = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos);
147:
148:
149: $fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2);
150:
151:
152: $recVer = (0x000F & $verInstance) >> 0;
153:
154: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
155: $recordData = substr($this->_data, $this->_pos + 8, $length);
156:
157:
158: $this->_pos += 8 + $length;
159: }
160:
161: 162: 163:
164: private function _readDggContainer()
165: {
166: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
167: $recordData = substr($this->_data, $this->_pos + 8, $length);
168:
169:
170: $this->_pos += 8 + $length;
171:
172:
173: $dggContainer = new PHPExcel_Shared_Escher_DggContainer();
174: $this->_object->setDggContainer($dggContainer);
175: $reader = new PHPExcel_Reader_Excel5_Escher($dggContainer);
176: $reader->load($recordData);
177: }
178:
179: 180: 181:
182: private function _readDgg()
183: {
184: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
185: $recordData = substr($this->_data, $this->_pos + 8, $length);
186:
187:
188: $this->_pos += 8 + $length;
189: }
190:
191: 192: 193:
194: private function _readBstoreContainer()
195: {
196: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
197: $recordData = substr($this->_data, $this->_pos + 8, $length);
198:
199:
200: $this->_pos += 8 + $length;
201:
202:
203: $bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer();
204: $this->_object->setBstoreContainer($bstoreContainer);
205: $reader = new PHPExcel_Reader_Excel5_Escher($bstoreContainer);
206: $reader->load($recordData);
207: }
208:
209: 210: 211:
212: private function _readBSE()
213: {
214:
215:
216:
217: $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;
218:
219: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
220: $recordData = substr($this->_data, $this->_pos + 8, $length);
221:
222:
223: $this->_pos += 8 + $length;
224:
225:
226: $BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE();
227: $this->_object->addBSE($BSE);
228:
229: $BSE->setBLIPType($recInstance);
230:
231:
232: $btWin32 = ord($recordData[0]);
233:
234:
235: $btMacOS = ord($recordData[1]);
236:
237:
238: $rgbUid = substr($recordData, 2, 16);
239:
240:
241: $tag = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 18);
242:
243:
244: $size = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 20);
245:
246:
247: $cRef = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 24);
248:
249:
250: $foDelay = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 28);
251:
252:
253: $unused1 = ord($recordData{32});
254:
255:
256: $cbName = ord($recordData{33});
257:
258:
259: $unused2 = ord($recordData{34});
260:
261:
262: $unused3 = ord($recordData{35});
263:
264:
265: $nameData = substr($recordData, 36, $cbName);
266:
267:
268: $blipData = substr($recordData, 36 + $cbName);
269:
270:
271: $reader = new PHPExcel_Reader_Excel5_Escher($BSE);
272: $reader->load($blipData);
273: }
274:
275: 276: 277:
278: private function _readBlipJPEG()
279: {
280:
281:
282:
283: $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;
284:
285: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
286: $recordData = substr($this->_data, $this->_pos + 8, $length);
287:
288:
289: $this->_pos += 8 + $length;
290:
291: $pos = 0;
292:
293:
294: $rgbUid1 = substr($recordData, 0, 16);
295: $pos += 16;
296:
297:
298: if (in_array($recInstance, array(0x046B, 0x06E3))) {
299: $rgbUid2 = substr($recordData, 16, 16);
300: $pos += 16;
301: }
302:
303:
304: $tag = ord($recordData{$pos});
305: $pos += 1;
306:
307:
308: $data = substr($recordData, $pos);
309:
310: $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip();
311: $blip->setData($data);
312:
313: $this->_object->setBlip($blip);
314: }
315:
316: 317: 318:
319: private function _readBlipPNG()
320: {
321:
322:
323:
324: $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;
325:
326: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
327: $recordData = substr($this->_data, $this->_pos + 8, $length);
328:
329:
330: $this->_pos += 8 + $length;
331:
332: $pos = 0;
333:
334:
335: $rgbUid1 = substr($recordData, 0, 16);
336: $pos += 16;
337:
338:
339: if ($recInstance == 0x06E1) {
340: $rgbUid2 = substr($recordData, 16, 16);
341: $pos += 16;
342: }
343:
344:
345: $tag = ord($recordData{$pos});
346: $pos += 1;
347:
348:
349: $data = substr($recordData, $pos);
350:
351: $blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip();
352: $blip->setData($data);
353:
354: $this->_object->setBlip($blip);
355: }
356:
357: 358: 359:
360: private function _readOPT()
361: {
362:
363:
364:
365: $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;
366:
367: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
368: $recordData = substr($this->_data, $this->_pos + 8, $length);
369:
370:
371: $this->_pos += 8 + $length;
372:
373: $this->_readOfficeArtRGFOPTE($recordData, $recInstance);
374: }
375:
376: 377: 378:
379: private function _readTertiaryOPT()
380: {
381:
382:
383:
384: $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;
385:
386: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
387: $recordData = substr($this->_data, $this->_pos + 8, $length);
388:
389:
390: $this->_pos += 8 + $length;
391: }
392:
393: 394: 395:
396: private function _readSplitMenuColors()
397: {
398: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
399: $recordData = substr($this->_data, $this->_pos + 8, $length);
400:
401:
402: $this->_pos += 8 + $length;
403: }
404:
405: 406: 407:
408: private function _readDgContainer()
409: {
410: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
411: $recordData = substr($this->_data, $this->_pos + 8, $length);
412:
413:
414: $this->_pos += 8 + $length;
415:
416:
417: $dgContainer = new PHPExcel_Shared_Escher_DgContainer();
418: $this->_object->setDgContainer($dgContainer);
419: $reader = new PHPExcel_Reader_Excel5_Escher($dgContainer);
420: $escher = $reader->load($recordData);
421: }
422:
423: 424: 425:
426: private function _readDg()
427: {
428: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
429: $recordData = substr($this->_data, $this->_pos + 8, $length);
430:
431:
432: $this->_pos += 8 + $length;
433: }
434:
435: 436: 437:
438: private function _readSpgrContainer()
439: {
440:
441:
442: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
443: $recordData = substr($this->_data, $this->_pos + 8, $length);
444:
445:
446: $this->_pos += 8 + $length;
447:
448:
449: $spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer();
450:
451: if ($this->_object instanceof PHPExcel_Shared_Escher_DgContainer) {
452:
453: $this->_object->setSpgrContainer($spgrContainer);
454: } else {
455:
456: $this->_object->addChild($spgrContainer);
457: }
458:
459: $reader = new PHPExcel_Reader_Excel5_Escher($spgrContainer);
460: $escher = $reader->load($recordData);
461: }
462:
463: 464: 465:
466: private function _readSpContainer()
467: {
468: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
469: $recordData = substr($this->_data, $this->_pos + 8, $length);
470:
471:
472: $spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();
473: $this->_object->addChild($spContainer);
474:
475:
476: $this->_pos += 8 + $length;
477:
478:
479: $reader = new PHPExcel_Reader_Excel5_Escher($spContainer);
480: $escher = $reader->load($recordData);
481: }
482:
483: 484: 485:
486: private function _readSpgr()
487: {
488: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
489: $recordData = substr($this->_data, $this->_pos + 8, $length);
490:
491:
492: $this->_pos += 8 + $length;
493: }
494:
495: 496: 497:
498: private function _readSp()
499: {
500:
501:
502:
503: $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;
504:
505: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
506: $recordData = substr($this->_data, $this->_pos + 8, $length);
507:
508:
509: $this->_pos += 8 + $length;
510: }
511:
512: 513: 514:
515: private function _readClientTextbox()
516: {
517:
518:
519:
520: $recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;
521:
522: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
523: $recordData = substr($this->_data, $this->_pos + 8, $length);
524:
525:
526: $this->_pos += 8 + $length;
527: }
528:
529: 530: 531:
532: private function _readClientAnchor()
533: {
534: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
535: $recordData = substr($this->_data, $this->_pos + 8, $length);
536:
537:
538: $this->_pos += 8 + $length;
539:
540:
541: $c1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 2);
542:
543:
544: $startOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 4);
545:
546:
547: $r1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 6);
548:
549:
550: $startOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 8);
551:
552:
553: $c2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 10);
554:
555:
556: $endOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 12);
557:
558:
559: $r2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 14);
560:
561:
562: $endOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 16);
563:
564:
565: $this->_object->setStartCoordinates(PHPExcel_Cell::stringFromColumnIndex($c1) . ($r1 + 1));
566:
567:
568: $this->_object->setStartOffsetX($startOffsetX);
569:
570:
571: $this->_object->setStartOffsetY($startOffsetY);
572:
573:
574: $this->_object->setEndCoordinates(PHPExcel_Cell::stringFromColumnIndex($c2) . ($r2 + 1));
575:
576:
577: $this->_object->setEndOffsetX($endOffsetX);
578:
579:
580: $this->_object->setEndOffsetY($endOffsetY);
581: }
582:
583: 584: 585:
586: private function _readClientData()
587: {
588: $length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);
589: $recordData = substr($this->_data, $this->_pos + 8, $length);
590:
591:
592: $this->_pos += 8 + $length;
593: }
594:
595: 596: 597: 598: 599: 600:
601: private function _readOfficeArtRGFOPTE($data, $n) {
602:
603: $splicedComplexData = substr($data, 6 * $n);
604:
605:
606: for ($i = 0; $i < $n; ++$i) {
607:
608: $fopte = substr($data, 6 * $i, 6);
609:
610:
611: $opid = PHPExcel_Reader_Excel5::_GetInt2d($fopte, 0);
612:
613:
614: $opidOpid = (0x3FFF & $opid) >> 0;
615:
616:
617: $opidFBid = (0x4000 & $opid) >> 14;
618:
619:
620: $opidFComplex = (0x8000 & $opid) >> 15;
621:
622:
623: $op = PHPExcel_Reader_Excel5::_GetInt4d($fopte, 2);
624:
625: if ($opidFComplex) {
626: $complexData = substr($splicedComplexData, 0, $op);
627: $splicedComplexData = substr($splicedComplexData, $op);
628:
629:
630: $value = $complexData;
631: } else {
632:
633: $value = $op;
634: }
635:
636: $this->_object->setOPT($opidOpid, $value);
637: }
638: }
639:
640: }
641: