ILIAS  eassessment Revision 61809
 All Data Structures Namespaces Files Functions Variables Groups Pages
Escher.php
Go to the documentation of this file.
1 <?php
37 {
41  private $_object;
42 
46  private $_data;
47 
53  private $_spOffsets;
54 
55 
61  public function __construct($object)
62  {
63  $this->_object = $object;
64  }
65 
69  public function close()
70  {
71  // initialize
72  $this->_data = '';
73 
74  switch (get_class($this->_object)) {
75 
76  case 'PHPExcel_Shared_Escher':
77  if ($dggContainer = $this->_object->getDggContainer()) {
78  $writer = new PHPExcel_Writer_Excel5_Escher($dggContainer);
79  $this->_data = $writer->close();
80  } else if ($dgContainer = $this->_object->getDgContainer()) {
81  $writer = new PHPExcel_Writer_Excel5_Escher($dgContainer);
82  $this->_data = $writer->close();
83  $this->_spOffsets = $writer->getSpOffsets();
84  }
85  break;
86 
87  case 'PHPExcel_Shared_Escher_DggContainer':
88  // this is a container record
89 
90  // initialize
91  $innerData = '';
92 
93  // write the dgg
94  $recVer = 0x0;
95  $recInstance = 0x0000;
96  $recType = 0xF006;
97 
98  $recVerInstance = $recVer;
99  $recVerInstance |= $recInstance << 4;
100 
101  // dgg data
102  $dggData =
103  pack('VVVV'
104  , $this->_object->getSpIdMax() // maximum shape identifier increased by one
105  , $this->_object->getCDgSaved() + 1 // number of file identifier clusters increased by one
106  , $this->_object->getCSpSaved()
107  , $this->_object->getCDgSaved() // count total number of drawings saved
108  );
109 
110  // add file identifier clusters (one per drawing)
111  $IDCLs = $this->_object->getIDCLs();
112 
113  foreach ($IDCLs as $dgId => $maxReducedSpId) {
114  $dggData .= pack('VV', $dgId, $maxReducedSpId + 1);
115  }
116 
117  $header = pack('vvV', $recVerInstance, $recType, strlen($dggData));
118  $innerData .= $header . $dggData;
119 
120  // write the bstoreContainer
121  if ($bstoreContainer = $this->_object->getBstoreContainer()) {
122  $writer = new PHPExcel_Writer_Excel5_Escher($bstoreContainer);
123  $innerData .= $writer->close();
124  }
125 
126  // write the record
127  $recVer = 0xF;
128  $recInstance = 0x0000;
129  $recType = 0xF000;
130  $length = strlen($innerData);
131 
132  $recVerInstance = $recVer;
133  $recVerInstance |= $recInstance << 4;
134 
135  $header = pack('vvV', $recVerInstance, $recType, $length);
136 
137  $this->_data = $header . $innerData;
138  break;
139 
140  case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer':
141  // this is a container record
142 
143  // initialize
144  $innerData = '';
145 
146  // treat the inner data
147  if ($BSECollection = $this->_object->getBSECollection()) {
148  foreach ($BSECollection as $BSE) {
149  $writer = new PHPExcel_Writer_Excel5_Escher($BSE);
150  $innerData .= $writer->close();
151  }
152  }
153 
154  // write the record
155  $recVer = 0xF;
156  $recInstance = count($this->_object->getBSECollection());
157  $recType = 0xF001;
158  $length = strlen($innerData);
159 
160  $recVerInstance = $recVer;
161  $recVerInstance |= $recInstance << 4;
162 
163  $header = pack('vvV', $recVerInstance, $recType, $length);
164 
165  $this->_data = $header . $innerData;
166  break;
167 
168  case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE':
169  // this is a semi-container record
170 
171  // initialize
172  $innerData = '';
173 
174  // here we treat the inner data
175  if ($blip = $this->_object->getBlip()) {
176  $writer = new PHPExcel_Writer_Excel5_Escher($blip);
177  $innerData .= $writer->close();
178  }
179 
180  // initialize
181  $data = '';
182 
183  $btWin32 = $this->_object->getBlipType();
184  $btMacOS = $this->_object->getBlipType();
185  $data .= pack('CC', $btWin32, $btMacOS);
186 
187  $rgbUid = pack('VVVV', 0,0,0,0); // todo
188  $data .= $rgbUid;
189 
190  $tag = 0;
191  $size = strlen($innerData);
192  $cRef = 1;
193  $foDelay = 0; //todo
194  $unused1 = 0x0;
195  $cbName = 0x0;
196  $unused2 = 0x0;
197  $unused3 = 0x0;
198  $data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3);
199 
200  $data .= $innerData;
201 
202  // write the record
203  $recVer = 0x2;
204  $recInstance = $this->_object->getBlipType();
205  $recType = 0xF007;
206  $length = strlen($data);
207 
208  $recVerInstance = $recVer;
209  $recVerInstance |= $recInstance << 4;
210 
211  $header = pack('vvV', $recVerInstance, $recType, $length);
212 
213  $this->_data = $header;
214 
215  $this->_data .= $data;
216  break;
217 
218  case 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip':
219  // this is an atom record
220 
221  // write the record
222  switch ($this->_object->getParent()->getBlipType()) {
223 
225  // initialize
226  $innerData = '';
227 
228  $rgbUid1 = pack('VVVV', 0,0,0,0); // todo
229  $innerData .= $rgbUid1;
230 
231  $tag = 0xFF; // todo
232  $innerData .= pack('C', $tag);
233 
234  $innerData .= $this->_object->getData();
235 
236  $recVer = 0x0;
237  $recInstance = 0x46A;
238  $recType = 0xF01D;
239  $length = strlen($innerData);
240 
241  $recVerInstance = $recVer;
242  $recVerInstance |= $recInstance << 4;
243 
244  $header = pack('vvV', $recVerInstance, $recType, $length);
245 
246  $this->_data = $header;
247 
248  $this->_data .= $innerData;
249  break;
250 
252  // initialize
253  $innerData = '';
254 
255  $rgbUid1 = pack('VVVV', 0,0,0,0); // todo
256  $innerData .= $rgbUid1;
257 
258  $tag = 0xFF; // todo
259  $innerData .= pack('C', $tag);
260 
261  $innerData .= $this->_object->getData();
262 
263  $recVer = 0x0;
264  $recInstance = 0x6E0;
265  $recType = 0xF01E;
266  $length = strlen($innerData);
267 
268  $recVerInstance = $recVer;
269  $recVerInstance |= $recInstance << 4;
270 
271  $header = pack('vvV', $recVerInstance, $recType, $length);
272 
273  $this->_data = $header;
274 
275  $this->_data .= $innerData;
276  break;
277 
278  }
279  break;
280 
281  case 'PHPExcel_Shared_Escher_DgContainer':
282  // this is a container record
283 
284  // initialize
285  $innerData = '';
286 
287  // write the dg
288  $recVer = 0x0;
289  $recInstance = $this->_object->getDgId();
290  $recType = 0xF008;
291  $length = 8;
292 
293  $recVerInstance = $recVer;
294  $recVerInstance |= $recInstance << 4;
295 
296  $header = pack('vvV', $recVerInstance, $recType, $length);
297 
298  // number of shapes in this drawing (including group shape)
299  $countShapes = count($this->_object->getSpgrContainer()->getChildren());
300  $innerData .= $header . pack('VV', $countShapes, $this->_object->getLastSpId());
301  //$innerData .= $header . pack('VV', 0, 0);
302 
303  // write the spgrContainer
304  if ($spgrContainer = $this->_object->getSpgrContainer()) {
305  $writer = new PHPExcel_Writer_Excel5_Escher($spgrContainer);
306  $innerData .= $writer->close();
307 
308  // get the shape offsets relative to the spgrContainer record
309  $spOffsets = $writer->getSpOffsets();
310 
311  // save the shape offsets relative to dgContainer
312  foreach ($spOffsets as & $spOffset) {
313  $spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes)
314  }
315 
316  $this->_spOffsets = $spOffsets;
317  }
318 
319  // write the record
320  $recVer = 0xF;
321  $recInstance = 0x0000;
322  $recType = 0xF002;
323  $length = strlen($innerData);
324 
325  $recVerInstance = $recVer;
326  $recVerInstance |= $recInstance << 4;
327 
328  $header = pack('vvV', $recVerInstance, $recType, $length);
329 
330  $this->_data = $header . $innerData;
331  break;
332 
333  case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer':
334  // this is a container record
335 
336  // initialize
337  $innerData = '';
338 
339  // initialize spape offsets
340  $totalSize = 8;
341  $spOffsets = array();
342 
343  // treat the inner data
344  foreach ($this->_object->getChildren() as $spContainer) {
345  $writer = new PHPExcel_Writer_Excel5_Escher($spContainer);
346  $spData = $writer->close();
347  $innerData .= $spData;
348 
349  // save the shape offsets (where new shape records begin)
350  $totalSize += strlen($spData);
351  $spOffsets[] = $totalSize;
352  }
353 
354  // write the record
355  $recVer = 0xF;
356  $recInstance = 0x0000;
357  $recType = 0xF003;
358  $length = strlen($innerData);
359 
360  $recVerInstance = $recVer;
361  $recVerInstance |= $recInstance << 4;
362 
363  $header = pack('vvV', $recVerInstance, $recType, $length);
364 
365  $this->_data = $header . $innerData;
366  $this->_spOffsets = $spOffsets;
367  break;
368 
369  case 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer':
370  // initialize
371  $data = '';
372 
373  // build the data
374 
375  // write group shape record, if necessary?
376  if ($this->_object->getSpgr()) {
377  $recVer = 0x1;
378  $recInstance = 0x0000;
379  $recType = 0xF009;
380  $length = 0x00000010;
381 
382  $recVerInstance = $recVer;
383  $recVerInstance |= $recInstance << 4;
384 
385  $header = pack('vvV', $recVerInstance, $recType, $length);
386 
387  $data .= $header . pack('VVVV', 0,0,0,0);
388  }
389 
390  // write the shape record
391  $recVer = 0x2;
392  $recInstance = $this->_object->getSpType(); // shape type
393  $recType = 0xF00A;
394  $length = 0x00000008;
395 
396  $recVerInstance = $recVer;
397  $recVerInstance |= $recInstance << 4;
398 
399  $header = pack('vvV', $recVerInstance, $recType, $length);
400 
401  $data .= $header . pack('VV', $this->_object->getSpId(), $this->_object->getSpgr() ? 0x0005 : 0x0A00);
402 
403 
404  // the options
405  if ($this->_object->getOPTCollection()) {
406  $optData = '';
407 
408  $recVer = 0x3;
409  $recInstance = count($this->_object->getOPTCollection());
410  $recType = 0xF00B;
411  foreach ($this->_object->getOPTCollection() as $property => $value) {
412  $optData .= pack('vV', $property, $value);
413  }
414  $length = strlen($optData);
415 
416  $recVerInstance = $recVer;
417  $recVerInstance |= $recInstance << 4;
418 
419  $header = pack('vvV', $recVerInstance, $recType, $length);
420  $data .= $header . $optData;
421  }
422 
423  // the client anchor
424  if ($this->_object->getStartCoordinates()) {
425  $clientAnchorData = '';
426 
427  $recVer = 0x0;
428  $recInstance = 0x0;
429  $recType = 0xF010;
430 
431  // start coordinates
432  list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getStartCoordinates());
433  $c1 = PHPExcel_Cell::columnIndexFromString($column) - 1;
434  $r1 = $row - 1;
435 
436  // start offsetX
437  $startOffsetX = $this->_object->getStartOffsetX();
438 
439  // start offsetY
440  $startOffsetY = $this->_object->getStartOffsetY();
441 
442  // end coordinates
443  list($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getEndCoordinates());
444  $c2 = PHPExcel_Cell::columnIndexFromString($column) - 1;
445  $r2 = $row - 1;
446 
447  // end offsetX
448  $endOffsetX = $this->_object->getEndOffsetX();
449 
450  // end offsetY
451  $endOffsetY = $this->_object->getEndOffsetY();
452 
453  $clientAnchorData = pack('vvvvvvvvv', 0x02,
454  $c1, $startOffsetX, $r1, $startOffsetY,
455  $c2, $endOffsetX, $r2, $endOffsetY);
456 
457  $length = strlen($clientAnchorData);
458 
459  $recVerInstance = $recVer;
460  $recVerInstance |= $recInstance << 4;
461 
462  $header = pack('vvV', $recVerInstance, $recType, $length);
463  $data .= $header . $clientAnchorData;
464  }
465 
466  // the client data, just empty for now
467  if (!$this->_object->getSpgr()) {
468  $clientDataData = '';
469 
470  $recVer = 0x0;
471  $recInstance = 0x0;
472  $recType = 0xF011;
473 
474  $length = strlen($clientDataData);
475 
476  $recVerInstance = $recVer;
477  $recVerInstance |= $recInstance << 4;
478 
479  $header = pack('vvV', $recVerInstance, $recType, $length);
480  $data .= $header . $clientDataData;
481  }
482 
483  // write the record
484  $recVer = 0xF;
485  $recInstance = 0x0000;
486  $recType = 0xF004;
487  $length = strlen($data);
488 
489  $recVerInstance = $recVer;
490  $recVerInstance |= $recInstance << 4;
491 
492  $header = pack('vvV', $recVerInstance, $recType, $length);
493 
494  $this->_data = $header . $data;
495  break;
496 
497  }
498 
499  return $this->_data;
500  }
501 
507  public function getSpOffsets()
508  {
509  return $this->_spOffsets;
510  }
511 
512 }