| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615 | <?php//============================================================+// File name   : makefont.php// Begin       : 2004-12-31// Last Update : 2010-08-08// Version     : 1.2.006// License     : GNU LGPL (http://www.gnu.org/copyleft/lesser.html)// 	----------------------------------------------------------------------------// 	Copyright (C) 2008-2010  Nicola Asuni - Tecnick.com S.r.l.// 	// This file is part of TCPDF software library.//// TCPDF is free software: you can redistribute it and/or modify it// under the terms of the GNU Lesser General Public License as// published by the Free Software Foundation, either version 3 of the// License, or (at your option) any later version.//// TCPDF is distributed in the hope that it will be useful, but// WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.// See the GNU Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public License// along with TCPDF.  If not, see <http://www.gnu.org/licenses/>.//// See LICENSE.TXT file for more information.//  ----------------------------------------------------------------------------//// Description : Utility to generate font definition files fot TCPDF//// Authors: Nicola Asuni, Olivier Plathey, Steven Wittens//// (c) Copyright://               Nicola Asuni//               Tecnick.com S.r.l.//               Via della Pace, 11//               09044 Quartucciu (CA)//               ITALY//               www.tecnick.com//               info@tecnick.com//============================================================+/** * Utility to generate font definition files fot TCPDF. * @author Nicola Asuni, Olivier Plathey, Steven Wittens * @copyright 2004-2008 Nicola Asuni - Tecnick.com S.r.l (www.tecnick.com) Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - info@tecnick.com * @package com.tecnick.tcpdf * @link http://www.tcpdf.org * @license http://www.gnu.org/copyleft/lesser.html LGPL*//** *  * @param string $fontfile path to font file (TTF, OTF or PFB). * @param string $fmfile font metrics file (UFM or AFM). * @param boolean $embedded Set to false to not embed the font, true otherwise (default). * @param string $enc Name of the encoding table to use. Omit this parameter for TrueType Unicode, OpenType Unicode and symbolic fonts like Symbol or ZapfDingBats. * @param array $patch Optional modification of the encoding */function MakeFont($fontfile, $fmfile, $embedded=true, $enc='cp1252', $patch=array()) {	//Generate a font definition file	set_magic_quotes_runtime(0);	ini_set('auto_detect_line_endings', '1');	if (!file_exists($fontfile)) {		die('Error: file not found: '.$fontfile);	}	if (!file_exists($fmfile)) {		die('Error: file not found: '.$fmfile);	}	$cidtogidmap = '';	$map = array();	$diff = '';	$dw = 0; // default width	$ffext = strtolower(substr($fontfile, -3));	$fmext = strtolower(substr($fmfile, -3));	if ($fmext == 'afm') {		if (($ffext == 'ttf') OR ($ffext == 'otf')) {			$type = 'TrueType';		} elseif ($ffext == 'pfb') {			$type = 'Type1';		} else {			die('Error: unrecognized font file extension: '.$ffext);		}		if ($enc) {			$map = ReadMap($enc);			foreach ($patch as $cc => $gn) {				$map[$cc] = $gn;			}		}		$fm = ReadAFM($fmfile, $map);		if (isset($widths['.notdef'])) {			$dw = $widths['.notdef'];		}		if ($enc) {			$diff = MakeFontEncoding($map);		}		$fd = MakeFontDescriptor($fm, empty($map));	} elseif ($fmext == 'ufm') {		$enc = '';		if (($ffext == 'ttf') OR ($ffext == 'otf')) {			$type = 'TrueTypeUnicode';		} else {			die('Error: not a TrueType font: '.$ffext);		}		$fm = ReadUFM($fmfile, $cidtogidmap);		$dw = $fm['MissingWidth'];		$fd = MakeFontDescriptor($fm, false);	}	//Start generation	$s = '<?php'."\n";	$s .= '$type=\''.$type."';\n";	$s .= '$name=\''.$fm['FontName']."';\n";	$s .= '$desc='.$fd.";\n";	if (!isset($fm['UnderlinePosition'])) {		$fm['UnderlinePosition'] = -100;	}	if (!isset($fm['UnderlineThickness'])) {		$fm['UnderlineThickness'] = 50;	}	$s .= '$up='.$fm['UnderlinePosition'].";\n";	$s .= '$ut='.$fm['UnderlineThickness'].";\n";	if ($dw <= 0) {		if (isset($fm['Widths'][32]) AND ($fm['Widths'][32] > 0)) {			// assign default space width			$dw = $fm['Widths'][32];		} else {			$dw = 600;		}	}	$s .= '$dw='.$dw.";\n";	$w = MakeWidthArray($fm);	$s .= '$cw='.$w.";\n";	$s .= '$enc=\''.$enc."';\n";	$s .= '$diff=\''.$diff."';\n";	$basename = substr(basename($fmfile), 0, -4);	if ($embedded) {		//Embedded font		if (($type == 'TrueType') OR ($type == 'TrueTypeUnicode')) {			CheckTTF($fontfile);		}		$f = fopen($fontfile,'rb');		if (!$f) {			die('Error: Unable to open '.$fontfile);		}		$file = fread($f, filesize($fontfile));		fclose($f);		if ($type == 'Type1') {			//Find first two sections and discard third one			$header = (ord($file{0}) == 128);			if ($header) {				//Strip first binary header				$file = substr($file, 6);			}			$pos = strpos($file, 'eexec');			if (!$pos) {				die('Error: font file does not seem to be valid Type1');			}			$size1 = $pos + 6;			if ($header AND (ord($file{$size1}) == 128)) {				//Strip second binary header				$file = substr($file, 0, $size1).substr($file, $size1+6);			}			$pos = strpos($file, '00000000');			if (!$pos) {				die('Error: font file does not seem to be valid Type1');			}			$size2 = $pos - $size1;			$file = substr($file, 0, ($size1 + $size2));		}		$basename = strtolower($basename);		if (function_exists('gzcompress')) {			$cmp = $basename.'.z';			SaveToFile($cmp, gzcompress($file, 9), 'b');			$s .= '$file=\''.$cmp."';\n";			print "Font file compressed (".$cmp.")\n";			if (!empty($cidtogidmap)) {				$cmp = $basename.'.ctg.z';				SaveToFile($cmp, gzcompress($cidtogidmap, 9), 'b');				print "CIDToGIDMap created and compressed (".$cmp.")\n";				$s .= '$ctg=\''.$cmp."';\n";			}		} else {			$s .= '$file=\''.basename($fontfile)."';\n";			print "Notice: font file could not be compressed (zlib extension not available)\n";			if (!empty($cidtogidmap)) {				$cmp = $basename.'.ctg';				$f = fopen($cmp, 'wb');				fwrite($f, $cidtogidmap);				fclose($f);				print "CIDToGIDMap created (".$cmp.")\n";				$s .= '$ctg=\''.$cmp."';\n";			}		}		if($type == 'Type1') {			$s .= '$size1='.$size1.";\n";			$s .= '$size2='.$size2.";\n";		} else {			$s.='$originalsize='.filesize($fontfile).";\n";		}	} else {		//Not embedded font		$s .= '$file='."'';\n";	}	$s .= '// --- EOF ---';	SaveToFile($basename.'.php',$s);	print "Font definition file generated (".$basename.".php)\n";}/** * Read the specified encoding map. * @param string $enc map name (see /enc/ folder for valid names). */function ReadMap($enc) {	//Read a map file	$file = dirname(__FILE__).'/enc/'.strtolower($enc).'.map';	$a = file($file);	if (empty($a)) {		die('Error: encoding not found: '.$enc);	}	$cc2gn = array();	foreach ($a as $l) {		if ($l{0} == '!') {			$e = preg_split('/[ \\t]+/',rtrim($l));			$cc = hexdec(substr($e[0],1));			$gn = $e[2];			$cc2gn[$cc] = $gn;		}	}	for($i = 0; $i <= 255; $i++) {		if(!isset($cc2gn[$i])) {			$cc2gn[$i] = '.notdef';		}	}	return $cc2gn;}/** * Read UFM file */function ReadUFM($file, &$cidtogidmap) {	//Prepare empty CIDToGIDMap	$cidtogidmap = str_pad('', (256 * 256 * 2), "\x00");	//Read a font metric file	$a = file($file);	if (empty($a)) {		die('File not found');	}	$widths = array();	$fm = array();	foreach($a as $l) {		$e = explode(' ',chop($l));		if(count($e) < 2) {			continue;		}		$code = $e[0];		$param = $e[1];		if($code == 'U') {			// U 827 ; WX 0 ; N squaresubnosp ; G 675 ;			//Character metrics			$cc = (int)$e[1];			if ($cc != -1) {			$gn = $e[7];			$w = $e[4];			$glyph = $e[10];			$widths[$cc] = $w;			if($cc == ord('X')) {				$fm['CapXHeight'] = $e[13];			}			// Set GID			if (($cc >= 0) AND ($cc < 0xFFFF) AND $glyph) {				$cidtogidmap{($cc * 2)} = chr($glyph >> 8);				$cidtogidmap{(($cc * 2) + 1)} = chr($glyph & 0xFF);			}		}		if((isset($gn) AND ($gn == '.notdef')) AND (!isset($fm['MissingWidth']))) {			$fm['MissingWidth'] = $w;		}		} elseif($code == 'FontName') {			$fm['FontName'] = $param;		} elseif($code == 'Weight') {			$fm['Weight'] = $param;		} elseif($code == 'ItalicAngle') {			$fm['ItalicAngle'] = (double)$param;		} elseif($code == 'Ascender') {			$fm['Ascender'] = (int)$param;		} elseif($code == 'Descender') {			$fm['Descender'] = (int)$param;		} elseif($code == 'UnderlineThickness') {			$fm['UnderlineThickness'] = (int)$param;		} elseif($code == 'UnderlinePosition') {			$fm['UnderlinePosition'] = (int)$param;		} elseif($code == 'IsFixedPitch') {			$fm['IsFixedPitch'] = ($param == 'true');		} elseif($code == 'FontBBox') {			$fm['FontBBox'] = array($e[1], $e[2], $e[3], $e[4]);		} elseif($code == 'CapHeight') {			$fm['CapHeight'] = (int)$param;		} elseif($code == 'StdVW') {			$fm['StdVW'] = (int)$param;		}	}	if(!isset($fm['MissingWidth'])) {		$fm['MissingWidth'] = 600;	}	if(!isset($fm['FontName'])) {		die('FontName not found');	}	$fm['Widths'] = $widths;	return $fm;}/** * Read AFM file */function ReadAFM($file,&$map) {	//Read a font metric file	$a = file($file);	if(empty($a)) {		die('File not found');	}	$widths = array();	$fm = array();	$fix = array(		'Edot'=>'Edotaccent',		'edot'=>'edotaccent',		'Idot'=>'Idotaccent',		'Zdot'=>'Zdotaccent',		'zdot'=>'zdotaccent',		'Odblacute' => 'Ohungarumlaut',		'odblacute' => 'ohungarumlaut',		'Udblacute'=>'Uhungarumlaut',		'udblacute'=>'uhungarumlaut',		'Gcedilla'=>'Gcommaaccent'		,'gcedilla'=>'gcommaaccent',		'Kcedilla'=>'Kcommaaccent',		'kcedilla'=>'kcommaaccent',		'Lcedilla'=>'Lcommaaccent',		'lcedilla'=>'lcommaaccent',		'Ncedilla'=>'Ncommaaccent',		'ncedilla'=>'ncommaaccent',		'Rcedilla'=>'Rcommaaccent',		'rcedilla'=>'rcommaaccent',		'Scedilla'=>'Scommaaccent',		'scedilla'=>'scommaaccent',		'Tcedilla'=>'Tcommaaccent',		'tcedilla'=>'tcommaaccent',		'Dslash'=>'Dcroat',		'dslash'=>'dcroat',		'Dmacron'=>'Dcroat',		'dmacron'=>'dcroat',		'combininggraveaccent'=>'gravecomb',		'combininghookabove'=>'hookabovecomb',		'combiningtildeaccent'=>'tildecomb',		'combiningacuteaccent'=>'acutecomb',		'combiningdotbelow'=>'dotbelowcomb',		'dongsign'=>'dong'		);	foreach($a as $l) {		$e = explode(' ', rtrim($l));		if (count($e) < 2) {			continue;		}		$code = $e[0];		$param = $e[1];		if ($code == 'C') {			//Character metrics			$cc = (int)$e[1];			$w = $e[4];			$gn = $e[7];			if (substr($gn, -4) == '20AC') {				$gn = 'Euro';			}			if (isset($fix[$gn])) {				//Fix incorrect glyph name				foreach ($map as $c => $n) {					if ($n == $fix[$gn]) {						$map[$c] = $gn;					}				}			}			if (empty($map)) {				//Symbolic font: use built-in encoding				$widths[$cc] = $w;			} else {				$widths[$gn] = $w;				if($gn == 'X') {					$fm['CapXHeight'] = $e[13];				}			}			if($gn == '.notdef') {				$fm['MissingWidth'] = $w;			}		} elseif($code == 'FontName') {			$fm['FontName'] = $param;		} elseif($code == 'Weight') {			$fm['Weight'] = $param;		} elseif($code == 'ItalicAngle') {			$fm['ItalicAngle'] = (double)$param;		} elseif($code == 'Ascender') {			$fm['Ascender'] = (int)$param;		} elseif($code == 'Descender') {			$fm['Descender'] = (int)$param;		} elseif($code == 'UnderlineThickness') {			$fm['UnderlineThickness'] = (int)$param;		} elseif($code == 'UnderlinePosition') {			$fm['UnderlinePosition'] = (int)$param;		} elseif($code == 'IsFixedPitch') {			$fm['IsFixedPitch'] = ($param == 'true');		} elseif($code == 'FontBBox') {			$fm['FontBBox'] = array($e[1], $e[2], $e[3], $e[4]);		} elseif($code == 'CapHeight') {			$fm['CapHeight'] = (int)$param;		} elseif($code == 'StdVW') {			$fm['StdVW'] = (int)$param;		}	}	if (!isset($fm['FontName'])) {		die('FontName not found');	}	if (!empty($map)) {		if (!isset($widths['.notdef'])) {			$widths['.notdef'] = 600;		}		if (!isset($widths['Delta']) AND isset($widths['increment'])) {			$widths['Delta'] = $widths['increment'];		}		//Order widths according to map		for ($i = 0; $i <= 255; $i++) {			if (!isset($widths[$map[$i]])) {				print "Warning: character ".$map[$i]." is missing\n";				$widths[$i] = $widths['.notdef'];			} else {				$widths[$i] = $widths[$map[$i]];			}		}	}	$fm['Widths'] = $widths;	return $fm;}function MakeFontDescriptor($fm, $symbolic=false) {	//Ascent	$asc = (isset($fm['Ascender']) ? $fm['Ascender'] : 1000);	$fd = "array('Ascent'=>".$asc;	//Descent	$desc = (isset($fm['Descender']) ? $fm['Descender'] : -200);	$fd .= ",'Descent'=>".$desc;	//CapHeight	if (isset($fm['CapHeight'])) {		$ch = $fm['CapHeight'];	} elseif (isset($fm['CapXHeight'])) {		$ch = $fm['CapXHeight'];	} else {		$ch = $asc;	}	$fd .= ",'CapHeight'=>".$ch;	//Flags	$flags = 0;	if (isset($fm['IsFixedPitch']) AND $fm['IsFixedPitch']) {		$flags += 1<<0;	}	if ($symbolic) {		$flags += 1<<2;	} else {		$flags += 1<<5;	}	if (isset($fm['ItalicAngle']) AND ($fm['ItalicAngle'] != 0)) {		$flags += 1<<6;	}	$fd .= ",'Flags'=>".$flags;	//FontBBox	if (isset($fm['FontBBox'])) {		$fbb = $fm['FontBBox'];	} else {		$fbb = array(0, ($desc - 100), 1000, ($asc + 100));	}	$fd .= ",'FontBBox'=>'[".$fbb[0].' '.$fbb[1].' '.$fbb[2].' '.$fbb[3]."]'";	//ItalicAngle	$ia = (isset($fm['ItalicAngle']) ? $fm['ItalicAngle'] : 0);	$fd .= ",'ItalicAngle'=>".$ia;	//StemV	if (isset($fm['StdVW'])) {		$stemv = $fm['StdVW'];	} elseif (isset($fm['Weight']) AND preg_match('/(bold|black)/i', $fm['Weight'])) {		$stemv = 120;	} else {		$stemv = 70;	}	$fd .= ",'StemV'=>".$stemv;	//MissingWidth	if(isset($fm['MissingWidth'])) {		$fd .= ",'MissingWidth'=>".$fm['MissingWidth'];	}	$fd .= ')';	return $fd;}function MakeWidthArray($fm) {	//Make character width array	$s = 'array(';	$cw = $fm['Widths'];	$els = array();	$c = 0;	foreach ($cw as $i => $w) {		if (is_numeric($i)) {			$els[] = (((($c++)%10) == 0) ? "\n" : '').$i.'=>'.$w;		}	}	$s .= implode(',', $els);	$s .= ')';	return $s;}function MakeFontEncoding($map) {	//Build differences from reference encoding	$ref = ReadMap('cp1252');	$s = '';	$last = 0;	for ($i = 32; $i <= 255; $i++) {		if ($map[$i] != $ref[$i]) {			if ($i != $last+1) {				$s .= $i.' ';			}			$last = $i;			$s .= '/'.$map[$i].' ';		}	}	return rtrim($s);}function SaveToFile($file, $s, $mode='t') {	$f = fopen($file, 'w'.$mode);	if(!$f) {		die('Can\'t write to file '.$file);	}	fwrite($f, $s, strlen($s));	fclose($f);}function ReadShort($f) {	$a = unpack('n1n', fread($f, 2));	return $a['n'];}function ReadLong($f) {	$a = unpack('N1N', fread($f, 4));	return $a['N'];}function CheckTTF($file) {	//Check if font license allows embedding	$f = fopen($file, 'rb');	if (!$f) {		die('Error: unable to open '.$file);	}	//Extract number of tables	fseek($f, 4, SEEK_CUR);	$nb = ReadShort($f);	fseek($f, 6, SEEK_CUR);	//Seek OS/2 table	$found = false;	for ($i = 0; $i < $nb; $i++) {		if (fread($f, 4) == 'OS/2') {			$found = true;			break;		}		fseek($f, 12, SEEK_CUR);	}	if (!$found) {		fclose($f);		return;	}	fseek($f, 4, SEEK_CUR);	$offset = ReadLong($f);	fseek($f, $offset, SEEK_SET);	//Extract fsType flags	fseek($f, 8, SEEK_CUR);	$fsType = ReadShort($f);	$rl = ($fsType & 0x02) != 0;	$pp = ($fsType & 0x04) != 0;	$e = ($fsType & 0x08) != 0;	fclose($f);	if($rl AND (!$pp) AND (!$e)) {		print "Warning: font license does not allow embedding\n";	}}$arg = $GLOBALS['argv'];if (count($arg) >= 3) {	ob_start();	array_shift($arg);	if (sizeof($arg) == 3) {		$arg[3] = $arg[2];		$arg[2] = true;	} else {		if (!isset($arg[2])) {			$arg[2] = true;		}		if (!isset($arg[3])) {			$arg[3] = 'cp1252';		}	}	if (!isset($arg[4])) {		$arg[4] = array();	}	MakeFont($arg[0], $arg[1], $arg[2], $arg[3], $arg[4]);	$t = ob_get_clean();	print preg_replace('!<BR( /)?>!i', "\n", $t);} else {	print "Usage: makefont.php <ttf/otf/pfb file> <afm/ufm file> <encoding> <patch>\n";}//============================================================+// END OF FILE                                                 //============================================================+
 |