function _putfonts()
{
$nf = $this->n;
foreach ($this->diffs as $diff) {
// Encodings
$this->_newobj();
$this->_out('<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [' . $diff . ']>>');
$this->_out('endobj');
}
foreach ($this->FontFiles as $file => $info) {
if (!isset($info['type']) || $info['type'] != 'TTF') {
// Font file embedding
$this->_newobj();
$this->FontFiles[$file]['n'] = $this->n;
$font = '';
$f = fopen($this->_getfontpath() . $file, 'rb', 1);
if (!$f) {
$this->Error('Font file not found');
}
while (!feof($f)) {
$font .= fread($f, 8192);
}
fclose($f);
$compressed = substr($file, -2) == '.z';
if (!$compressed && isset($info['length2'])) {
$header = ord($font[0]) == 128;
if ($header) {
// Strip first binary header
$font = substr($font, 6);
}
if ($header && ord($font[$info['length1']]) == 128) {
// Strip second binary header
$font = substr($font, 0, $info['length1']) . substr($font, $info['length1'] + 6);
}
}
$this->_out('<</Length ' . strlen($font));
if ($compressed) {
$this->_out('/Filter /FlateDecode');
}
$this->_out('/Length1 ' . $info['length1']);
if (isset($info['length2'])) {
$this->_out('/Length2 ' . $info['length2'] . ' /Length3 0');
}
$this->_out('>>');
$this->_putstream($font);
$this->_out('endobj');
}
}
foreach ($this->fonts as $k => $font) {
// Font objects
//$this->fonts[$k]['n']=$this->n+1;
$type = $font['type'];
$name = $font['name'];
if ($type == 'Core') {
// Standard font
$this->fonts[$k]['n'] = $this->n + 1;
$this->_newobj();
$this->_out('<</Type /Font');
$this->_out('/BaseFont /' . $name);
$this->_out('/Subtype /Type1');
if ($name != 'Symbol' && $name != 'ZapfDingbats') {
$this->_out('/Encoding /WinAnsiEncoding');
}
$this->_out('>>');
$this->_out('endobj');
} elseif ($type == 'Type1' || $type == 'TrueType') {
// Additional Type1 or TrueType font
$this->fonts[$k]['n'] = $this->n + 1;
$this->_newobj();
$this->_out('<</Type /Font');
$this->_out('/BaseFont /' . $name);
$this->_out('/Subtype /' . $type);
$this->_out('/FirstChar 32 /LastChar 255');
$this->_out('/Widths ' . ($this->n + 1) . ' 0 R');
$this->_out('/FontDescriptor ' . ($this->n + 2) . ' 0 R');
if ($font['enc']) {
if (isset($font['diff'])) {
$this->_out('/Encoding ' . ($nf + $font['diff']) . ' 0 R');
} else {
$this->_out('/Encoding /WinAnsiEncoding');
}
}
$this->_out('>>');
$this->_out('endobj');
// Widths
$this->_newobj();
$cw =& $font['cw'];
$s = '[';
for ($i = 32; $i <= 255; $i++) {
$s .= $cw[chr($i)] . ' ';
}
$this->_out($s . ']');
$this->_out('endobj');
// Descriptor
$this->_newobj();
$s = '<</Type /FontDescriptor /FontName /' . $name;
foreach ($font['desc'] as $k => $v) {
$s .= ' /' . $k . ' ' . $v;
}
$file = $font['file'];
if ($file) {
$s .= ' /FontFile' . ($type == 'Type1' ? '' : '2') . ' ' . $this->FontFiles[$file]['n'] . ' 0 R';
}
$this->_out($s . '>>');
$this->_out('endobj');
} else {
if ($type == 'TTF') {
$this->fonts[$k]['n'] = $this->n + 1;
require_once $this->_getfontpath() . 'unifont/ttfonts.php';
$ttf = new TTFontFile();
$fontname = 'MPDFAA' . '+' . $font['name'];
$subset = $font['subset'];
unset($subset[0]);
$ttfontstream = $ttf->makeSubset($font['ttffile'], $subset);
$ttfontsize = strlen($ttfontstream);
$fontstream = gzcompress($ttfontstream);
$codeToGlyph = $ttf->codeToGlyph;
unset($codeToGlyph[0]);
// Type0 Font
// A composite font - a font composed of other fonts, organized hierarchically
$this->_newobj();
$this->_out('<</Type /Font');
$this->_out('/Subtype /Type0');
$this->_out('/BaseFont /' . $fontname . '');
$this->_out('/Encoding /Identity-H');
$this->_out('/DescendantFonts [' . ($this->n + 1) . ' 0 R]');
$this->_out('/ToUnicode ' . ($this->n + 2) . ' 0 R');
$this->_out('>>');
$this->_out('endobj');
// CIDFontType2
// A CIDFont whose glyph descriptions are based on TrueType font technology
$this->_newobj();
$this->_out('<</Type /Font');
$this->_out('/Subtype /CIDFontType2');
$this->_out('/BaseFont /' . $fontname . '');
$this->_out('/CIDSystemInfo ' . ($this->n + 2) . ' 0 R');
$this->_out('/FontDescriptor ' . ($this->n + 3) . ' 0 R');
if (isset($font['desc']['MissingWidth'])) {
$this->_out('/DW ' . $font['desc']['MissingWidth'] . '');
}
$this->_putTTfontwidths($font, $ttf->maxUni);
$this->_out('/CIDToGIDMap ' . ($this->n + 4) . ' 0 R');
$this->_out('>>');
$this->_out('endobj');
// ToUnicode
$this->_newobj();
$toUni = "/CIDInit /ProcSet findresource begin\n";
$toUni .= "12 dict begin\n";
$toUni .= "begincmap\n";
$toUni .= "/CIDSystemInfo\n";
$toUni .= "<</Registry (Adobe)\n";
$toUni .= "/Ordering (UCS)\n";
$toUni .= "/Supplement 0\n";
$toUni .= ">> def\n";
$toUni .= "/CMapName /Adobe-Identity-UCS def\n";
$toUni .= "/CMapType 2 def\n";
$toUni .= "1 begincodespacerange\n";
$toUni .= "<0000> <FFFF>\n";
$toUni .= "endcodespacerange\n";
$toUni .= "1 beginbfrange\n";
$toUni .= "<0000> <FFFF> <0000>\n";
$toUni .= "endbfrange\n";
$toUni .= "endcmap\n";
$toUni .= "CMapName currentdict /CMap defineresource pop\n";
$toUni .= "end\n";
$toUni .= "end";
$this->_out('<</Length ' . strlen($toUni) . '>>');
$this->_putstream($toUni);
$this->_out('endobj');
// CIDSystemInfo dictionary
$this->_newobj();
$this->_out('<</Registry (Adobe)');
$this->_out('/Ordering (UCS)');
$this->_out('/Supplement 0');
$this->_out('>>');
$this->_out('endobj');
// Font descriptor
$this->_newobj();
$this->_out('<</Type /FontDescriptor');
$this->_out('/FontName /' . $fontname);
foreach ($font['desc'] as $kd => $v) {
if ($kd == 'Flags') {
$v = $v | 4;
$v = $v & ~32;
}
// SYMBOLIC font flag
$this->_out(' /' . $kd . ' ' . $v);
}
$this->_out('/FontFile2 ' . ($this->n + 2) . ' 0 R');
$this->_out('>>');
$this->_out('endobj');
// Embed CIDToGIDMap
// A specification of the mapping from CIDs to glyph indices
$cidtogidmap = '';
$cidtogidmap = str_pad('', 256 * 256 * 2, "");
foreach ($codeToGlyph as $cc => $glyph) {
$cidtogidmap[$cc * 2] = chr($glyph >> 8);
$cidtogidmap[$cc * 2 + 1] = chr($glyph & 0xff);
}
$cidtogidmap = gzcompress($cidtogidmap);
$this->_newobj();
$this->_out('<</Length ' . strlen($cidtogidmap) . '');
$this->_out('/Filter /FlateDecode');
$this->_out('>>');
$this->_putstream($cidtogidmap);
$this->_out('endobj');
//Font file
$this->_newobj();
$this->_out('<</Length ' . strlen($fontstream));
$this->_out('/Filter /FlateDecode');
$this->_out('/Length1 ' . $ttfontsize);
$this->_out('>>');
$this->_putstream($fontstream);
$this->_out('endobj');
unset($ttf);
} else {
// Allow for additional types
$this->fonts[$k]['n'] = $this->n + 1;
$mtd = '_put' . strtolower($type);
if (!method_exists($this, $mtd)) {
$this->Error('Unsupported font type: ' . $type);
}
$this->{$mtd}($font);
}
}
}
}