/** * Parse a page object from a string * * @param string $stream * @return PageObject */ public static function parse($stream) { $page = new self(); $page->setIndex(substr($stream, 0, strpos($stream, ' '))); // Determine the page parent object index. $parent = substr($stream, strpos($stream, '/Parent') + 7); $parent = trim(substr($parent, 0, strpos($parent, '0 R'))); $page->setParentIndex($parent); // Determine the page width and height. $dims = substr($stream, strpos($stream, '/MediaBox') + 9); $dims = substr($dims, 0, strpos($dims, ']')); $dims = trim(str_replace('[', '', $dims)); $dims = explode(' ', $dims); $page->setWidth($dims[2]); $page->setHeight($dims[3]); // Determine the page content objects. if (strpos($stream, '/Contents') !== false) { $contents = substr($stream, strpos($stream, '/Contents') + 9); $contents = $page->getDictionaryReferences($contents); foreach ($contents as $content) { $page->addContentIndex($content); } // Set placeholder $contents = substr($stream, strpos($stream, '/Contents') + 9); if (strpos($contents, '[') !== false) { $contents = substr($contents, 0, strpos($contents, ']') + 1); $stream = str_replace($contents, '[{content_objects}]', $stream); } else { $contents = strpos($contents, '/') !== false ? substr($contents, 0, strpos($contents, '/')) : substr($contents, 0, strpos($contents, '>')); $stream = str_replace($contents, '[{content_objects}]', $stream); } } // If they exist, determine the page annotation objects. if (strpos($stream, '/Annots') !== false) { $annots = substr($stream, strpos($stream, '/Annots') + 7); $annots = $page->getDictionaryReferences($annots); foreach ($annots as $annot) { $page->addAnnotIndex($annot); } // Set placeholder $annots = substr($stream, strpos($stream, '/Annots') + 7); if (strpos($annots, '[') !== false) { $annots = substr($annots, 0, strpos($annots, ']') + 1); $stream = str_replace($annots, '[{annotations}]', $stream); } else { $annots = strpos($annots, '/') !== false ? substr($annots, 0, strpos($annots, '/')) : substr($annots, 0, strpos($annots, '>')); $stream = str_replace($annots, '[{annotations}]', $stream); } } // If they exist, determine the page font references. if (strpos($stream, '/Font') !== false) { $fonts = substr($stream, strpos($stream, 'Font')); $fonts = substr($fonts, 0, strpos($fonts, '>>') + 2); $stream = str_replace('/' . $fonts, '[{fonts}]', $stream); $fonts = str_replace('Font<<', '', $fonts); $fonts = str_replace('>>', '', $fonts); $fonts = explode('/', $fonts); foreach ($fonts as $value) { if ($value != '') { $page->addFontReference('/' . $value); } } } // If they exist, determine the page XObjects references. if (strpos($stream, '/XObject') !== false) { $xo = substr($stream, strpos($stream, 'XObject')); $xo = substr($xo, 0, strpos($xo, '>>') + 2); $stream = str_replace('/' . $xo, '[{xobjects}]', $stream); $xo = str_replace('XObject<<', '', $xo); $xo = str_replace('>>', '', $xo); $xo = explode('/', $xo); foreach ($xo as $value) { if ($value != '') { $page->addXObjectReference('/' . $value); } } } // If they exist, determine the page graphic states. if (strpos($stream, '/ExtGState') !== false) { $gState = substr($stream, strpos($stream, 'ExtGState')); $gState = '/' . substr($gState, 0, strpos($gState, '>>') + 2); } else { $gState = ''; } // If any groups exist if (strpos($stream, '/Group') !== false) { $group = substr($stream, strpos($stream, 'Group')); $group = '/' . substr($group, 0, strpos($group, '>>') + 2); } else { $group = ''; } // If resources exists if (strpos($stream, '/Resources') !== false) { $resources = substr($stream, strpos($stream, 'Resources')); if (strpos($resources, ' R') !== false) { $resources = '/' . substr($resources, 0, strpos($resources, ' R') + 2); } else { if (strpos($resources, '>>') !== false) { $resources = '/' . substr($resources, 0, strpos($resources, '>>') + 2); } else { $resources = "/Resources<</ProcSet[/PDF/Text/ImageB/ImageC/ImageI][{xobjects}][{fonts}]{$gState}>>"; } } } else { $resources = "/Resources<</ProcSet[/PDF/Text/ImageB/ImageC/ImageI][{xobjects}][{fonts}]{$gState}>>"; } if (substr_count($resources, '<<') > substr_count($resources, '>>')) { $resources .= str_repeat('>>', substr_count($resources, '<<') - substr_count($resources, '>>')); } $page->setData("\n[{page_index}] 0 obj\n<</Type/Page/Parent [{parent}] 0 R[{annotations}]/MediaBox" . "[0 0 [{width}] [{height}]]{$group}[{content_objects}]{$resources}>>\nendobj\n"); return $page; }