private function readRecordDocumentContainer($stream, $pos)
{
$documentAtom = $this->loadRecordHeader($stream, $pos);
$pos += 8;
if ($documentAtom['recVer'] != 0x1 || $documentAtom['recInstance'] != 0x0 || $documentAtom['recType'] != self::RT_DOCUMENTATOM) {
throw new \Exception('File PowerPoint 97 in error (Location : RTDocument > DocumentAtom).');
}
$pos += $documentAtom['recLen'];
$exObjList = $this->loadRecordHeader($stream, $pos);
if ($exObjList['recVer'] == 0xf && $exObjList['recInstance'] == 0x0 && $exObjList['recType'] == self::RT_EXTERNALOBJECTLIST) {
$pos += 8;
// exObjListAtom > rh
$exObjListAtom = $this->loadRecordHeader($stream, $pos);
if ($exObjListAtom['recVer'] != 0x0 || $exObjListAtom['recInstance'] != 0x0 || $exObjListAtom['recType'] != self::RT_EXTERNALOBJECTLISTATOM || $exObjListAtom['recLen'] != 0x4) {
throw new \Exception('File PowerPoint 97 in error (Location : RTDocument > DocumentAtom > exObjList > exObjListAtom).');
}
$pos += 8;
// exObjListAtom > exObjIdSeed
$pos += 4;
// rgChildRec
$exObjList['recLen'] -= 12;
do {
$childRec = $this->loadRecordHeader($stream, $pos);
$pos += 8;
$exObjList['recLen'] -= 8;
switch ($childRec['recType']) {
case self::RT_EXTERNALHYPERLINK:
//@link : http://msdn.microsoft.com/en-us/library/dd944995(v=office.12).aspx
// exHyperlinkAtom > rh
$exHyperlinkAtom = $this->loadRecordHeader($stream, $pos);
if ($exHyperlinkAtom['recVer'] != 0x0 || $exHyperlinkAtom['recInstance'] != 0x0 || $exHyperlinkAtom['recType'] != self::RT_EXTERNALHYPERLINKATOM || $exObjListAtom['recLen'] != 0x4) {
throw new \Exception('File PowerPoint 97 in error (Location : RTDocument > DocumentAtom > exObjList > rgChildRec > RT_ExternalHyperlink).');
}
$pos += 8;
$exObjList['recLen'] -= 8;
// exHyperlinkAtom > exHyperlinkId
$exHyperlinkId = self::getInt4d($stream, $pos);
$pos += 4;
$exObjList['recLen'] -= 4;
$this->arrayHyperlinks[$exHyperlinkId] = array();
// friendlyNameAtom
$friendlyNameAtom = $this->loadRecordHeader($stream, $pos);
if ($friendlyNameAtom['recVer'] == 0x0 && $friendlyNameAtom['recInstance'] == 0x0 && $friendlyNameAtom['recType'] == self::RT_CSTRING && $friendlyNameAtom['recLen'] % 2 == 0) {
$pos += 8;
$exObjList['recLen'] -= 8;
$this->arrayHyperlinks[$exHyperlinkId]['text'] = '';
for ($inc = 0; $inc < $friendlyNameAtom['recLen'] / 2; $inc++) {
$char = self::getInt2d($stream, $pos);
$pos += 2;
$exObjList['recLen'] -= 2;
$this->arrayHyperlinks[$exHyperlinkId]['text'] .= chr($char);
}
}
// targetAtom
$targetAtom = $this->loadRecordHeader($stream, $pos);
if ($targetAtom['recVer'] == 0x0 && $targetAtom['recInstance'] == 0x1 && $targetAtom['recType'] == self::RT_CSTRING && $targetAtom['recLen'] % 2 == 0) {
$pos += 8;
$exObjList['recLen'] -= 8;
$this->arrayHyperlinks[$exHyperlinkId]['url'] = '';
for ($inc = 0; $inc < $targetAtom['recLen'] / 2; $inc++) {
$char = self::getInt2d($stream, $pos);
$pos += 2;
$exObjList['recLen'] -= 2;
$this->arrayHyperlinks[$exHyperlinkId]['url'] .= chr($char);
}
}
// locationAtom
$locationAtom = $this->loadRecordHeader($stream, $pos);
if ($locationAtom['recVer'] == 0x0 && $locationAtom['recInstance'] == 0x3 && $locationAtom['recType'] == self::RT_CSTRING && $locationAtom['recLen'] % 2 == 0) {
$pos += 8;
$exObjList['recLen'] -= 8;
$string = '';
for ($inc = 0; $inc < $locationAtom['recLen'] / 2; $inc++) {
$char = self::getInt2d($stream, $pos);
$pos += 2;
$exObjList['recLen'] -= 2;
$string .= chr($char);
}
}
break;
default:
throw new \Exception('Feature not implemented (l.' . __LINE__ . ' : ' . dechex($childRec['recType'] . ')'));
}
} while ($exObjList['recLen'] > 0);
}
//@link : http://msdn.microsoft.com/en-us/library/dd907813(v=office.12).aspx
$documentTextInfo = $this->loadRecordHeader($stream, $pos);
if ($documentTextInfo['recVer'] == 0xf && $documentTextInfo['recInstance'] == 0x0 && $documentTextInfo['recType'] == self::RT_ENVIRONMENT) {
$pos += 8;
//@link : http://msdn.microsoft.com/en-us/library/dd952717(v=office.12).aspx
$kinsoku = $this->loadRecordHeader($stream, $pos);
if ($kinsoku['recVer'] == 0xf && $kinsoku['recInstance'] == 0x2 && $kinsoku['recType'] == self::RT_KINSOKU) {
$pos += 8;
$pos += $kinsoku['recLen'];
}
//@link : http://msdn.microsoft.com/en-us/library/dd948152(v=office.12).aspx
$fontCollection = $this->loadRecordHeader($stream, $pos);
if ($fontCollection['recVer'] == 0xf && $fontCollection['recInstance'] == 0x0 && $fontCollection['recType'] == self::RT_FONTCOLLECTION) {
$pos += 8;
do {
$fontEntityAtom = $this->loadRecordHeader($stream, $pos);
$pos += 8;
$fontCollection['recLen'] -= 8;
if ($fontEntityAtom['recVer'] != 0x0 || $fontEntityAtom['recInstance'] > 128 || $fontEntityAtom['recType'] != self::RT_FONTENTITYATOM) {
throw new \Exception('File PowerPoint 97 in error (Location : RTDocument > RT_Environment > RT_FontCollection > RT_FontEntityAtom).');
}
$string = '';
for ($inc = 0; $inc < 32; $inc++) {
$char = self::getInt2d($stream, $pos);
$pos += 2;
$fontCollection['recLen'] -= 2;
$string .= chr($char);
}
$this->arrayFonts[] = $string;
// lfCharSet (1 byte)
$pos += 1;
$fontCollection['recLen'] -= 1;
// fEmbedSubsetted (1 bit)
// unused (7 bits)
$pos += 1;
$fontCollection['recLen'] -= 1;
// rasterFontType (1 bit)
// deviceFontType (1 bit)
// truetypeFontType (1 bit)
// fNoFontSubstitution (1 bit)
// reserved (4 bits)
$pos += 1;
$fontCollection['recLen'] -= 1;
// lfPitchAndFamily (1 byte)
$pos += 1;
$fontCollection['recLen'] -= 1;
$fontEmbedData1 = $this->loadRecordHeader($stream, $pos);
if ($fontEmbedData1['recVer'] == 0x0 && $fontEmbedData1['recInstance'] >= 0x0 && $fontEmbedData1['recInstance'] <= 0x3 && $fontEmbedData1['recType'] == self::RT_FONTEMBEDDATABLOB) {
$pos += 8;
$fontCollection['recLen'] -= 8;
$pos += $fontEmbedData1['recLen'];
$fontCollection['recLen'] -= $fontEmbedData1['recLen'];
}
$fontEmbedData2 = $this->loadRecordHeader($stream, $pos);
if ($fontEmbedData2['recVer'] == 0x0 && $fontEmbedData2['recInstance'] >= 0x0 && $fontEmbedData2['recInstance'] <= 0x3 && $fontEmbedData2['recType'] == self::RT_FONTEMBEDDATABLOB) {
$pos += 8;
$fontCollection['recLen'] -= 8;
$pos += $fontEmbedData2['recLen'];
$fontCollection['recLen'] -= $fontEmbedData2['recLen'];
}
$fontEmbedData3 = $this->loadRecordHeader($stream, $pos);
if ($fontEmbedData3['recVer'] == 0x0 && $fontEmbedData3['recInstance'] >= 0x0 && $fontEmbedData3['recInstance'] <= 0x3 && $fontEmbedData3['recType'] == self::RT_FONTEMBEDDATABLOB) {
$pos += 8;
$fontCollection['recLen'] -= 8;
$pos += $fontEmbedData3['recLen'];
$fontCollection['recLen'] -= $fontEmbedData3['recLen'];
}
$fontEmbedData4 = $this->loadRecordHeader($stream, $pos);
if ($fontEmbedData4['recVer'] == 0x0 && $fontEmbedData4['recInstance'] >= 0x0 && $fontEmbedData4['recInstance'] <= 0x3 && $fontEmbedData4['recType'] == self::RT_FONTEMBEDDATABLOB) {
$pos += 8;
$fontCollection['recLen'] -= 8;
$pos += $fontEmbedData4['recLen'];
$fontCollection['recLen'] -= $fontEmbedData4['recLen'];
}
} while ($fontCollection['recLen'] > 0);
}
}
}