Ejemplo n.º 1
0
 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'] != 'TrueTypesubset') {
             //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 == 'TrueTypesubset') {
                 $ssfaid = "A";
                 include_once $this->_getfontpath() . 'unifont/ttfonts.php';
                 $ttf = new TTFontFile();
                 $ttf->getMetrics($font['file'], 1);
                 for ($sfid = 0; $sfid < count($font['subsetfontids']); $sfid++) {
                     $this->fonts[$k]['n'][$sfid] = $this->n + 1;
                     // NB an array for subset
                     $subsetname = 'MPDFA' . $ssfaid . '+' . $font['name'];
                     $ssfaid++;
                     $subset = $font['subsets'][$sfid];
                     unset($subset[0]);
                     $ttfontstream = $ttf->makeSubset($subset);
                     $ttfontsize = strlen($ttfontstream);
                     $fontstream = gzcompress($ttfontstream);
                     $widthstring = '';
                     $toUnistring = '';
                     foreach ($font['subsets'][$sfid] as $cp => $u) {
                         if (isset($font['cw'][$u])) {
                             $widthstring .= $font['cw'][$u] . ' ';
                         } else {
                             $widthstring .= $ttf->defaultWidth . ' ';
                         }
                         $toUnistring .= sprintf("<%02s> <%04s>\n", strtoupper(dechex($cp)), strtoupper(dechex($u)));
                     }
                     //Additional Type1 or TrueType font
                     $this->_newobj();
                     $this->_out('<</Type /Font');
                     $this->_out('/BaseFont /' . $subsetname);
                     $this->_out('/Subtype /TrueType');
                     $this->_out('/FirstChar 0 /LastChar ' . count($font['subsets'][$sfid]));
                     $this->_out('/Widths ' . ($this->n + 1) . ' 0 R');
                     $this->_out('/FontDescriptor ' . ($this->n + 2) . ' 0 R');
                     $this->_out('/ToUnicode ' . ($this->n + 3) . ' 0 R');
                     $this->_out('>>');
                     $this->_out('endobj');
                     //Widths
                     $this->_newobj();
                     $this->_out('[' . $widthstring . ']');
                     $this->_out('endobj');
                     //Descriptor
                     $this->_newobj();
                     $s = '<</Type /FontDescriptor /FontName /' . $subsetname . "\n";
                     foreach ($font['desc'] as $kd => $v) {
                         if ($kd == 'Flags') {
                             $v = $v | 4;
                             $v = $v & ~32;
                         }
                         $s .= ' /' . $kd . ' ' . $v . "\n";
                     }
                     $s .= '/FontFile2 ' . ($this->n + 2) . ' 0 R';
                     $this->_out($s . '>>');
                     $this->_out('endobj');
                     // ToUnicode
                     $toUni = "stream\n";
                     $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 .= "<00> <FF>\n";
                     $toUni .= "endcodespacerange\n";
                     $toUni .= count($font['subsets'][$sfid]) . " beginbfchar\n";
                     $toUni .= $toUnistring;
                     $toUni .= "endbfchar\n";
                     $toUni .= "endcmap\n";
                     $toUni .= "CMapName currentdict /CMap defineresource pop\n";
                     $toUni .= "end\n";
                     $toUni .= "end\n";
                     $toUni .= "endstream\n";
                     $toUni .= "endobj";
                     $this->_newobj();
                     $this->_out('<</Length ' . (strlen($toUni) - 24) . '>>');
                     $this->_out($toUni);
                     //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);
             }
         }
     }
 }
Ejemplo n.º 2
0
 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);
             }
         }
     }
 }
Ejemplo n.º 3
0
            }
        }
    }
}
// loads array $unicode_ranges
include 'UnicodeRanges.php';
//==============================================================
$html = '<html><head><style>td { border: 0.1mm solid #555555; } 
body { font-weight: normal; font-family: helvetica;font-size:8pt; }
td { font-family: helvetica;font-size:8pt; vertical-align: top;}
</style></head><body>';
//==============================================================
$ff = scandir($ttfdir);
$tempfontdata = array();
foreach ($ff as $f) {
    $ttf = new TTFontFile();
    $ret = array();
    $isTTC = false;
    if (strtolower(substr($f, -4, 4)) == '.ttf' || strtolower(substr($f, -4, 4)) == '.otf') {
        $ret[] = $ttf->extractCoreInfo($ttfdir . $f);
    }
    for ($i = 0; $i < count($ret); $i++) {
        if (is_array($ret[$i])) {
            $tfname = $ret[$i][0];
            $bold = $ret[$i][1];
            $italic = $ret[$i][2];
            $fname = strtolower($tfname);
            $fname = preg_replace('/[ ()]/', '', $fname);
            //$tempfonttrans[$tfname] = $fname;
            $style = '';
            if ($bold) {
Ejemplo n.º 4
0
include "../mpdf.php";
$mpdf = new mPDF('s');
$mpdf->useSubstitutions = true;
if ($checkdir) {
    $ttfdir = $checkdir;
} else {
    $ttfdir = _MPDF_TTFONTPATH;
}
$mqr = ini_get("magic_quotes_runtime");
if ($mqr) {
    set_magic_quotes_runtime(0);
}
if (!class_exists('TTFontFile', false)) {
    include _MPDF_PATH . 'classes/ttfontsuni.php';
}
$ttf = new TTFontFile();
$tempfontdata = array();
$tempsansfonts = array();
$tempseriffonts = array();
$tempmonofonts = array();
$tempfonttrans = array();
$ff = scandir($ttfdir);
foreach ($ff as $f) {
    $ret = array();
    $isTTC = false;
    if (strtolower(substr($f, -4, 4)) == '.ttc' || strtolower(substr($f, -5, 5)) == '.ttcf') {
        // Mac ttcf
        $isTTC = true;
        $ttf->getTTCFonts($ttfdir . $f);
        $nf = $ttf->numTTCFonts;
        for ($i = 1; $i <= $nf; $i++) {
Ejemplo n.º 5
0
function _putfonts() {
	$nf=$this->n;
	foreach($this->FontFiles as $fontkey=>$info) {
	   // TrueType embedded
	   if (isset($info['type']) && $info['type']=='TTF' && !$info['sip'] && !$info['smp']) {
		$used = true;
		$asSubset = false;
		foreach($this->fonts AS $k=>$f) {
			if ($f['fontkey'] == $fontkey && $f['type']=='TTF') { 
				$used = $f['used']; 
				if ($used) {
					$nChars = (ord($f['cw'][0]) << 8) + ord($f['cw'][1]);
					$usage = intval(count($f['subset'])*100 / $nChars);
					$fsize = $info['length1'];
					// Always subset the very large TTF files
					if ($fsize > ($this->maxTTFFilesize *1024)) { $asSubset = true; }
					else if ($usage < $this->percentSubset) { $asSubset = true; }
				}
				if ($f['unAGlyphs']) $aaSubset = true;	// mPDF 5.4.05
				if ($this->PDFA || $this->PDFX)  $asSubset = false;
				$this->fonts[$k]['asSubset'] = $asSubset;
				break;
			}
		}
		if ($used && !$asSubset) {
			//Font file embedding
			$this->_newobj();
			$this->FontFiles[$fontkey]['n']=$this->n;
			$font='';
			$originalsize = $info['length1'];
			if ($this->repackageTTF || $this->fonts[$fontkey]['TTCfontID']>0) {
				// First see if there is a cached compressed file
				if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z')) {
					$f=fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z','rb');
					if(!$f) { $this->Error('Font file .ps.z not found'); }
					while(!feof($f)) { $font .= fread($f, 2048); }
					fclose($f);
					include(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.php');	// sets $originalsize (of repackaged font)
				}
				else {
					if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
					$ttf = new TTFontFile();
					$font = $ttf->repackageTTF($this->FontFiles[$fontkey]['ttffile'], $this->fonts[$fontkey]['TTCfontID'], $this->debugfonts, $this->fonts[$fontkey]['unAGlyphs']);	// mPDF 5.4.05

					$originalsize = strlen($font);
					$font = gzcompress($font);
					unset($ttf);
					if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
						$fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.z',"wb");
						fwrite($fh,$font,strlen($font));
						fclose($fh);
						$fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.ps.php',"wb");
						$len = "<?php \n";
						$len.='$originalsize='.$originalsize.";\n";
						$len.="?>";
						fwrite($fh,$len,strlen($len));
						fclose($fh);
					}
				}
			}
			else {
				// First see if there is a cached compressed file
				if (file_exists(_MPDF_TTFONTDATAPATH.$fontkey.'.z')) {
					$f=fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.z','rb');
					if(!$f) { $this->Error('Font file not found'); }
					while(!feof($f)) { $font .= fread($f, 2048); }
					fclose($f);
				}
				else {
					$f=fopen($this->FontFiles[$fontkey]['ttffile'],'rb');
					if(!$f) { $this->Error('Font file not found'); }
					while(!feof($f)) { $font .= fread($f, 2048); }
					fclose($f);
					$font = gzcompress($font);
					if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
						$fh = fopen(_MPDF_TTFONTDATAPATH.$fontkey.'.z',"wb");
						fwrite($fh,$font,strlen($font));
						fclose($fh);
					}
				}
			}

			$this->_out('<</Length '.strlen($font));
			$this->_out('/Filter /FlateDecode');
			$this->_out('/Length1 '.$originalsize);
			$this->_out('>>');
			$this->_putstream($font);
			$this->_out('endobj');
		}
	   }
	}

	$nfonts = count($this->fonts);
	$fctr = 1;
	foreach($this->fonts as $k=>$font) {
		//Font objects
		$type=$font['type'];
		$name=$font['name'];
		if ((!isset($font['used']) || !$font['used']) && $type=='TTF') { continue; }
		if ($this->progressBar) { $this->UpdateProgressBar(2,intval($fctr*100/$nfonts),'Writing Fonts'); $fctr++; }	// *PROGRESS-BAR*
		if (isset($font['asSubset'])) { $asSubset = $font['asSubset']; }
		else { $asSubset = ''; }
/*-- CJK-FONTS --*/
		if($type=='Type0') { 	// = Adobe CJK Fonts
			$this->fonts[$k]['n']=$this->n+1;
			$this->_newobj();
			$this->_out('<</Type /Font');
			$this->_putType0($font);
		}
		else
/*-- END CJK-FONTS --*/
		if($type=='core') {
			//Standard font
			$this->fonts[$k]['n']=$this->n+1;
			if ($this->PDFA || $this->PDFX) { $this->Error('Core fonts are not allowed in PDF/A1-b or PDFX/1-a files (Times, Helvetica, Courier etc.)'); }
			$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');
		} 
		// TrueType embedded SUBSETS for SIP (CJK extB containing Supplementary Ideographic Plane 2)
		// Or Unicode Plane 1 - Supplementary Multilingual Plane
		else if ($type=='TTF' && ($font['sip'] || $font['smp'])) {
		   if (!$font['used']) { continue; }
		   $ssfaid="AA";
		   if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
		   $ttf = new TTFontFile();
		   for($sfid=0;$sfid<count($font['subsetfontids']);$sfid++) {
			$this->fonts[$k]['n'][$sfid]=$this->n+1;		// NB an array for subset
			$subsetname = 'MPDF'.$ssfaid.'+'.$font['name'];
			$ssfaid++;
			$subset = $font['subsets'][$sfid];
			unset($subset[0]);
			$ttfontstream = $ttf->makeSubsetSIP($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts);
			$ttfontsize = strlen($ttfontstream);
			$fontstream = gzcompress($ttfontstream);
			$widthstring = '';
			$toUnistring = '';
			foreach($font['subsets'][$sfid] AS $cp=>$u) {
				$w = $this->_getCharWidth($font['cw'], $u); 
				if ($w !== false) {
					$widthstring .= $w.' ';
				}
				else {
					$widthstring .= round($ttf->defaultWidth).' ';
				}
				if ($u > 65535) {
					$utf8 = chr(($u>>18)+240).chr((($u>>12)&63)+128).chr((($u>>6)&63)+128) .chr(($u&63)+128);
					$utf16 = mb_convert_encoding($utf8, 'UTF-16BE', 'UTF-8');
					$l1 = ord($utf16[0]);
					$h1 = ord($utf16[1]);
					$l2 = ord($utf16[2]);
					$h2 = ord($utf16[3]);
					$toUnistring .= sprintf("<%02s> <%02s%02s%02s%02s>\n", strtoupper(dechex($cp)), strtoupper(dechex($l1)), strtoupper(dechex($h1)), strtoupper(dechex($l2)), strtoupper(dechex($h2)));
				}
				else {
					$toUnistring .= sprintf("<%02s> <%04s>\n", strtoupper(dechex($cp)), strtoupper(dechex($u)));
				}
			}

			//Additional Type1 or TrueType font
			$this->_newobj();
			$this->_out('<</Type /Font');
			$this->_out('/BaseFont /'.$subsetname);
			$this->_out('/Subtype /TrueType');
			$this->_out('/FirstChar 0 /LastChar '.(count($font['subsets'][$sfid])-1));
			$this->_out('/Widths '.($this->n+1).' 0 R');
			$this->_out('/FontDescriptor '.($this->n+2).' 0 R');
			$this->_out('/ToUnicode '.($this->n + 3).' 0 R');
			$this->_out('>>');
			$this->_out('endobj');

			//Widths
			$this->_newobj();
			$this->_out('['.$widthstring.']');
			$this->_out('endobj');

			//Descriptor
			$this->_newobj();
			$s='<</Type /FontDescriptor /FontName /'.$subsetname."\n";
			foreach($font['desc'] as $kd=>$v) {
				if ($kd == 'Flags') { $v = $v | 4; $v = $v & ~32; }	// SYMBOLIC font flag
				$s.=' /'.$kd.' '.$v."\n";
			}
			$s.='/FontFile2 '.($this->n + 2).' 0 R';
			$this->_out($s.'>>');
			$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 .= "<00> <FF>\n";
			$toUni .= "endcodespacerange\n";
			$toUni .= count($font['subsets'][$sfid])." beginbfchar\n";
			$toUni .= $toUnistring;
			$toUni .= "endbfchar\n";
			$toUni .= "endcmap\n";
			$toUni .= "CMapName currentdict /CMap defineresource pop\n";
			$toUni .= "end\n";
			$toUni .= "end\n";

			$this->_out('<</Length '.(strlen($toUni)).'>>');
			$this->_putstream($toUni);
			$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');
		   }	// foreach subset
		   unset($ttf);
		} 
		// TrueType embedded SUBSETS or FULL
		else if ($type=='TTF') {
			$this->fonts[$k]['n']=$this->n+1;
			if ($asSubset ) {
				$ssfaid="A";
				if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
				$ttf = new TTFontFile();
				$fontname = 'MPDFA'.$ssfaid.'+'.$font['name'];
				$subset = $font['subset'];
				unset($subset[0]);
				$ttfontstream = $ttf->makeSubset($font['ttffile'], $subset, $font['TTCfontID'], $this->debugfonts, $font['unAGlyphs']);	// mPDF 5.4.05
				$ttfontsize = strlen($ttfontstream);
				$fontstream = gzcompress($ttfontstream);
				$codeToGlyph = $ttf->codeToGlyph;
				unset($codeToGlyph[0]);
			}
			else { $fontname = $font['name']; }
			// 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'].''); 
			}

			if (!$asSubset && file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw')) {
					$w = '';
					$w=file_get_contents(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cw');
					$this->_out($w);
			}
			else {
				$this->_putTTfontwidths($font, $asSubset, $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\n";
			$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 ($asSubset && $kd == 'Flags') { $v = $v | 4; $v = $v & ~32; }	// SYMBOLIC font flag
				$this->_out(' /'.$kd.' '.$v);
			}
			if ($font['panose']) {
				$this->_out(' /Style << /Panose <'.$font['panose'].'> >>');
			}
			if ($asSubset ) {
				$this->_out('/FontFile2 '.($this->n + 2).' 0 R');
			}
			else if ($font['fontkey']) {
				// obj ID of a stream containing a TrueType font program
				$this->_out('/FontFile2 '.$this->FontFiles[$font['fontkey']]['n'].' 0 R');
			}
			$this->_out('>>');
			$this->_out('endobj');

			// Embed CIDToGIDMap
			// A specification of the mapping from CIDs to glyph indices
			if ($asSubset ) {
				$cidtogidmap = '';
				$cidtogidmap = str_pad('', 256*256*2, "\x00");
				foreach($codeToGlyph as $cc=>$glyph) {
					$cidtogidmap[$cc*2] = chr($glyph >> 8);
					$cidtogidmap[$cc*2 + 1] = chr($glyph & 0xFF);
				}
				$cidtogidmap = gzcompress($cidtogidmap);
			}
			else {
				// First see if there is a cached CIDToGIDMapfile
				$cidtogidmap = '';
				if (file_exists(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm')) {
					$f=fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm','rb');
					while(!feof($f)) { $cidtogidmap .= fread($f, 2048); }
					fclose($f);
				}
				else {
					if (!class_exists('TTFontFile', false)) { include(_MPDF_PATH .'classes/ttfontsuni.php'); }
					$ttf = new TTFontFile();
					$charToGlyph = $ttf->getCTG($font['ttffile'], $font['TTCfontID'], $this->debugfonts, $font['unAGlyphs']);	// mPDF 5.4.05
					$cidtogidmap = str_pad('', 256*256*2, "\x00");
					foreach($charToGlyph as $cc=>$glyph) {
						$cidtogidmap[$cc*2] = chr($glyph >> 8);
						$cidtogidmap[$cc*2 + 1] = chr($glyph & 0xFF);
					}
					unset($ttf);
					$cidtogidmap = gzcompress($cidtogidmap);
					if (is_writable(dirname(_MPDF_TTFONTDATAPATH.'x'))) {
						$fh = fopen(_MPDF_TTFONTDATAPATH.$font['fontkey'].'.cgm',"wb");
						fwrite($fh,$cidtogidmap,strlen($cidtogidmap));
						fclose($fh);
					}
				}
			}
			$this->_newobj();
			$this->_out('<</Length '.strlen($cidtogidmap).'');
			$this->_out('/Filter /FlateDecode');
			$this->_out('>>');
			$this->_putstream($cidtogidmap);
			$this->_out('endobj');

			//Font file 
			if ($asSubset ) {
				$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 { $this->Error('Unsupported font type: '.$type.' ('.$name.')'); }
	}
}
Ejemplo n.º 6
0
 /**
  * Add a TrueType, OpenType or Type1 font
  *
  * @param $family
  * @param string $style
  * @param string $file
  * @param bool $uni
  */
 public function addFont($family, $style = '', $file = '', $uni = false)
 {
     $family = strtolower($family);
     $style = strtoupper($style);
     $fontPath = $this->_pdfOutput->getDocument()->getFontPath();
     if ($style == 'IB') {
         $style = 'BI';
     }
     if ($file == '') {
         if ($uni) {
             $file = str_replace(' ', '', $family) . strtolower($style) . '.ttf';
         } else {
             $file = str_replace(' ', '', $family) . strtolower($style) . '.php';
         }
     }
     $fontkey = $family . $style;
     if (isset($this->fonts[$fontkey])) {
         return;
     }
     if ($uni) {
         if (defined("_SYSTEM_TTFONTS") && file_exists(_SYSTEM_TTFONTS . $file)) {
             $ttffilename = _SYSTEM_TTFONTS . $file;
         } else {
             $ttffilename = $fontPath . 'Unifonts/' . $file;
         }
         $unifilename = $fontPath . 'Unifonts/' . strtolower(substr($file, 0, strpos($file, '.')));
         $name = '';
         $originalsize = 0;
         $ttfstat = @stat($ttffilename);
         if (file_exists($unifilename . '.mtx.php')) {
             include $unifilename . '.mtx.php';
         }
         if (!isset($type) || !isset($name) || $originalsize != $ttfstat['size']) {
             $ttffile = $ttffilename;
             require_once $fontPath . 'Unifonts/ttfonts.php';
             $ttf = new \TTFontFile();
             $ttf->getMetrics($ttffile);
             $cw = $ttf->charWidths;
             $name = preg_replace('/[ ()]/', '', $ttf->fullName);
             $desc = array('Ascent' => round($ttf->ascent), 'Descent' => round($ttf->descent), 'CapHeight' => round($ttf->capHeight), 'Flags' => $ttf->flags, 'FontBBox' => '[' . round($ttf->bbox[0]) . " " . round($ttf->bbox[1]) . " " . round($ttf->bbox[2]) . " " . round($ttf->bbox[3]) . ']', 'ItalicAngle' => $ttf->italicAngle, 'StemV' => round($ttf->stemV), 'MissingWidth' => round($ttf->defaultWidth));
             $up = round($ttf->underlinePosition);
             $ut = round($ttf->underlineThickness);
             $originalsize = $ttfstat['size'] + 0;
             $type = 'TTF';
             // Generate metrics .php file
             $s = '<?php' . "\n";
             $s .= '$name         = \'' . $name . "';\n";
             $s .= '$type         = \'' . $type . "';\n";
             $s .= '$desc         = ' . var_export($desc, true) . ";\n";
             $s .= '$up           = ' . $up . ";\n";
             $s .= '$ut           = ' . $ut . ";\n";
             $s .= '$ttffile      = \'' . $ttffile . "';\n";
             $s .= '$originalsize = ' . $originalsize . ";\n";
             $s .= '$fontkey      = \'' . $fontkey . "';\n";
             if (is_writable(dirname($this->_pdfOutput->getDocument()->getFontPath() . 'Unifonts/' . 'x'))) {
                 $fh = fopen($unifilename . '.mtx.php', "w");
                 fwrite($fh, $s, strlen($s));
                 fclose($fh);
                 $fh = fopen($unifilename . '.cw.dat', "wb");
                 fwrite($fh, $cw, strlen($cw));
                 fclose($fh);
                 @unlink($unifilename . '.cw127.php');
             }
             unset($ttf);
         } else {
             $cw = @file_get_contents($unifilename . '.cw.dat');
         }
         $i = count($this->fonts) + 1;
         $aliasNbPages = $this->_pdfOutput->getDocument()->getAliasNbPages();
         if (!empty($aliasNbPages)) {
             $sbarr = range(0, 57);
         } else {
             $sbarr = range(0, 32);
         }
         $this->fonts[$fontkey] = array('i' => $i, 'type' => $type, 'name' => $name, 'desc' => $desc, 'up' => $up, 'ut' => $ut, 'cw' => $cw, 'ttffile' => $ttffile, 'fontkey' => $fontkey, 'subset' => $sbarr, 'unifilename' => $unifilename);
         $this->_fontFiles[$fontkey] = array('length1' => $originalsize, 'type' => "TTF", 'ttffile' => $ttffile);
         $this->_fontFiles[$file] = array('type' => "TTF");
         unset($cw);
     } else {
         $info = $this->_loadfont($file);
         $info['i'] = count($this->fonts) + 1;
         if (!empty($info['diff'])) {
             $n = array_search($info['diff'], $this->_diffs);
             if (!$n) {
                 $n = count($this->_diffs) + 1;
                 $this->_diffs[$n] = $info['diff'];
             }
             $info['diffn'] = $n;
         }
         if (!empty($info['file'])) {
             if ($info['type'] == 'TrueType') {
                 $this->_fontFiles[$info['file']] = array('length1' => $info['originalsize']);
             } else {
                 $this->_fontFiles[$info['file']] = array('length1' => $info['size1'], 'length2' => $info['size2']);
             }
         }
         $this->fonts[$fontkey] = $info;
     }
 }