/** * Get instance. */ public static function getInstance() { if (!self::$instance) { self::$instance = new IdmlFontManager(); } return self::$instance; }
/** The readDesignMap function obtains the filename pointers to the MasterSpreads, Resources, Spreads, * Stories, and XML from the designmap, which is the manifest that contains references to the names and locations * of the package's XML files. * * @return boolean true on success, false on failure. */ public function readDesignMap() { //first read the BackStory.xml file to see if any Stories, Hyperlinks, etc. should be ignored ... $this->readBackingStoryAndSetHiddenIds(); // The designmap contains references to everything in the package $designmap = $this->tempDir . '/designmap.xml'; if (!file_exists($designmap)) { $this->idmlAssembler->getProgressUpdater()->setWarning("{$designmap} does not exist."); return false; } // create DOMDocument and DOMXPath objects $doc = new DomDocument(); $b = $doc->load($designmap); if ($b === false) { return false; } $xpath = new DOMXPath($doc); // Parse the preferences file, which contains the width and height of our pages $tags = $xpath->query('//idPkg:Preferences'); assert($tags->length == 1); $attr = $tags->item(0)->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $this->preferences = new IdmlPreferences(); $this->preferences->load($filename); IdmlAssembler::updateBookSize($this->preferences->pageWidth, $this->preferences->pageHeight); // The Declaration Manager deals with declared Colors, declared Styles, and declared Style Groups $manager = IdmlDeclarationManager::getInstance(); // Parse the graphics file which contains color declarations (this must be done before parsing the Styles) $tags = $xpath->query('//idPkg:Graphic'); assert($tags->length == 1); $attr = $tags->item(0)->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $manager->loadDeclaredColors($filename); // There should always be exactly one Styles file *** Version 2: non-PEARSON *** $tags = $xpath->query('//idPkg:Styles'); assert($tags->length == 1); $attr = $tags->item(0)->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $manager->loadDeclaredStyles($filename); /* // There should always be exactly one Styles file *** Version 1: PEARSON PXE *** $tags = $xpath->query('//idPkg:Styles'); assert( $tags->length == 1 ); $attr = $tags->item(0)->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $this->style = new IdmlStyles($this); $this->style->filename = $filename; $this->style->load(); */ // Parse fonts file. $tags = $xpath->query('//idPkg:Fonts'); assert($tags->length == 1); $attr = $tags->item(0)->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; IdmlFontManager::getInstance()->loadFonts($filename); // There should always be exactly one Tags file $tags = $xpath->query('//idPkg:Tags'); assert($tags->length == 1); $attr = $tags->item(0)->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $this->tags = new IdmlTags($this); $this->tags->filename = $filename; $this->tags->load(); // There are possibly several MasterSpread files, which are referenced by real spreads and accessed by their UID's. $tags = $xpath->query('//idPkg:MasterSpread'); foreach ($tags as $tag) { $attr = $tag->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $matches = null; $found = preg_match('|MasterSpreads/MasterSpread_(.*)\\.xml|', $attr->value, $matches); // u154 <-- MasterSpreads/MasterSpread_u154.xml if ($found == 1) { $UID = $matches[1]; $masterSpread = new IdmlMasterSpread($this); $masterSpread->filename = $filename; $this->masterSpreads[$UID] = $masterSpread; } else { $this->idmlAssembler->getProgressUpdater()->setWarning("Unable to determine UID for MasterSpread '{$attr->value}'."); } } // There are most likely many Spread files, and they are ordered in the designmap // according to the book's page ordering. $tags = $xpath->query('//idPkg:Spread'); foreach ($tags as $tag) { $attr = $tag->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $spread = new IdmlSpread($this); $spread->filename = $filename; $this->spreads[] = $spread; } // There are most likely many Story files, which are referenced by TextFrames and accessed by a parentStoryUID. $tags = $xpath->query('//idPkg:Story'); foreach ($tags as $tag) { $attr = $tag->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $matches = null; $found = preg_match('|Stories/Story_(.*)\\.xml|', $attr->value, $matches); // u154 <-- Stories/Story_u154.xml if ($found == 1) { $UID = $matches[1]; if (!array_key_exists($UID, $this->chaucerHidden)) { //create/store the story if it is not hidden by a designer $story = new IdmlStory($UID); $story->filename = $filename; $this->stories[$UID] = $story; } } else { $this->idmlAssembler->getProgressUpdater()->setWarning("Unable to determine UID for Story '{$attr->value}'."); } } //Parse hyperlink information $this->hyperlinks = array(); $tags = $xpath->query('//Hyperlink'); $hyperlinkMgr = IdmlHyperlinkManager::getInstance(); foreach ($tags as $tag) { $properties = IdmlParserHelper::getAllDomNodeAttributesAndProperties($tag); // This code is (we think) PXE processing code if (!array_key_exists($properties['Self'], $this->chaucerHidden)) { // create/store the hyperlink if it is not hidden by a designer // The $destNode can be either a HyperlinkURLDestination or a HyperlinkPageDestination in the IDML, // and is referenced by the Hyperlink element. $destId = $properties['Destination']; $destNode = $xpath->query('//*[@Self="' . $destId . '"]'); if ($destNode->length > 0) { $destNode = $destNode->item(0); $properties['Destination'] = IdmlParserHelper::getAllDomNodeAttributesAndProperties($destNode); $properties['Destination']['DestinationType'] = $destNode->nodeName; } $this->hyperlinks[$properties['Self']] = $properties; } // The remainder of this foreach is specifically written for non-PXE IDML $hyperlinkSource = $properties['Source']; $external = false; // unless the link goes to a page outside the epub // If the Destination property is an array, the destination is a link to either // a page within the epub (with the page UID in the data), or or an external link. // So the destination can be set here. if (is_array($properties['Destination'])) { $anchor = false; // link is to a page, not an anchor if ($properties['Destination']['DestinationType'] == 'HyperlinkURLDestination') { // External page: use as is $hyperlinkDestination = $properties['Destination']['DestinationURL']; $external = true; // This links to a page outside the epub } else { // Internal page. Use the page UID; add the package index and the .html suffix $hyperlinkDestination = $properties['Destination']['DestinationPage']; } } else { $anchor = true; // link is to an anchor on a page. $hyperlinkDestination = 'Hyperlink_' . $properties['DestinationUniqueKey']; } $hyperlinkMgr->setSourceDestination($hyperlinkSource, $hyperlinkDestination, $anchor, $external); } //Parse layer information $layers = $xpath->query('//Layer'); $layerManager = IdmlLayerManager::getInstance(); foreach ($layers as $layer) { $layerManager->addLayer($layer); } return true; }