/** * Create a bookmark PDF string. * @protected * @author Olivier Plathey, Nicola Asuni * @since 2.1.002 (2008-02-12) */ protected function _putbookmarks() { $nb = count($this->outlines); if ($nb == 0) { return; } // sort bookmarks $this->sortBookmarks(); $lru = array(); $level = 0; foreach ($this->outlines as $i => $o) { if ($o['l'] > 0) { $parent = $lru[$o['l'] - 1]; //Set parent and last pointers $this->outlines[$i]['parent'] = $parent; $this->outlines[$parent]['last'] = $i; if ($o['l'] > $level) { //Level increasing: set first pointer $this->outlines[$parent]['first'] = $i; } } else { $this->outlines[$i]['parent'] = $nb; } if ($o['l'] <= $level and $i > 0) { //Set prev and next pointers $prev = $lru[$o['l']]; $this->outlines[$prev]['next'] = $i; $this->outlines[$i]['prev'] = $prev; } $lru[$o['l']] = $i; $level = $o['l']; } //Outline items $n = $this->n + 1; $nltags = '/<br[\\s]?\\/>|<\\/(blockquote|dd|dl|div|dt|h1|h2|h3|h4|h5|h6|hr|li|ol|p|pre|ul|tcpdf|table|tr|td)>/si'; foreach ($this->outlines as $i => $o) { $oid = $this->_newobj(); // covert HTML title to string $title = preg_replace($nltags, "\n", $o['t']); $title = preg_replace("/[\r]+/si", '', $title); $title = preg_replace("/[\n]+/si", "\n", $title); $title = strip_tags($title); $title = $this->stringTrim($title); $out = '<</Title ' . $this->_textstring($title, $oid); $out .= ' /Parent ' . ($n + $o['parent']) . ' 0 R'; if (isset($o['prev'])) { $out .= ' /Prev ' . ($n + $o['prev']) . ' 0 R'; } if (isset($o['next'])) { $out .= ' /Next ' . ($n + $o['next']) . ' 0 R'; } if (isset($o['first'])) { $out .= ' /First ' . ($n + $o['first']) . ' 0 R'; } if (isset($o['last'])) { $out .= ' /Last ' . ($n + $o['last']) . ' 0 R'; } if (isset($o['u']) and !empty($o['u'])) { // link if (is_string($o['u'])) { if ($o['u'][0] == '#') { // internal destination $out .= ' /Dest /' . TCPDF_STATIC::encodeNameObject(substr($o['u'], 1)); } elseif ($o['u'][0] == '%') { // embedded PDF file $filename = basename(substr($o['u'], 1)); $out .= ' /A <</S /GoToE /D [0 /Fit] /NewWindow true /T << /R /C /P ' . ($o['p'] - 1) . ' /A ' . $this->embeddedfiles[$filename]['a'] . ' >> >>'; } elseif ($o['u'][0] == '*') { // embedded generic file $filename = basename(substr($o['u'], 1)); $jsa = 'var D=event.target.doc;var MyData=D.dataObjects;for (var i in MyData) if (MyData[i].path=="' . $filename . '") D.exportDataObject( { cName : MyData[i].name, nLaunch : 2});'; $out .= ' /A <</S /JavaScript /JS ' . $this->_textstring($jsa, $oid) . '>>'; } else { // external URI link $out .= ' /A <</S /URI /URI ' . $this->_datastring($this->unhtmlentities($o['u']), $oid) . '>>'; } } elseif (isset($this->links[$o['u']])) { // internal link ID $l = $this->links[$o['u']]; if (isset($this->page_obj_id[$l[0]])) { $out .= sprintf(' /Dest [%u 0 R /XYZ 0 %F null]', $this->page_obj_id[$l[0]], $this->pagedim[$l[0]]['h'] - $l[1] * $this->k); } } } elseif (isset($this->page_obj_id[$o['p']])) { // link to a page $out .= ' ' . sprintf('/Dest [%u 0 R /XYZ %F %F null]', $this->page_obj_id[$o['p']], $o['x'] * $this->k, $this->pagedim[$o['p']]['h'] - $o['y'] * $this->k); } // set font style $style = 0; if (!empty($o['s'])) { // bold if (strpos($o['s'], 'B') !== false) { $style |= 2; } // oblique if (strpos($o['s'], 'I') !== false) { $style |= 1; } } $out .= sprintf(' /F %d', $style); // set bookmark color if (isset($o['c']) and is_array($o['c']) and count($o['c']) == 3) { $color = array_values($o['c']); $out .= sprintf(' /C [%F %F %F]', $color[0] / 255, $color[1] / 255, $color[2] / 255); } else { // black $out .= ' /C [0.0 0.0 0.0]'; } $out .= ' /Count 0'; // normally closed item $out .= ' >>'; $out .= "\n" . 'endobj'; $this->_out($out); } //Outline root $this->OutlineRoot = $this->_newobj(); $this->_out('<< /Type /Outlines /First ' . $n . ' 0 R /Last ' . ($n + $lru[0]) . ' 0 R >>' . "\n" . 'endobj'); }