Viewing file: makefont.php (10.16 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php /******************************************************************************* * Utility to generate font definition files * * Version: 1.13 * * Date: 2004-12-31 * *******************************************************************************/
function ReadMap($enc) { //Read a map file $file=dirname(__FILE__).'/'.strtolower($enc).'.map'; $a=file($file); if(empty($a)) die('<B>Error:</B> 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; }
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]])) { echo '<B>Warning:</B> character '.$map[$i].' is missing<BR>'; $widths[$i]=$widths['.notdef']; } else $widths[$i]=$widths[$map[$i]]; } } $fm['Widths']=$widths; return $fm; }
function MakeFontDescriptor($fm,$symbolic) { //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; if(!$symbolic) $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,$des-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 eregi('(bold|black)',$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(\n\t"; $cw=$fm['Widths']; for($i=0;$i<=255;$i++) { if(chr($i)=="'") $s.="'\\''"; elseif(chr($i)=="\\") $s.="'\\\\'"; elseif($i>=32 and $i<=126) $s.="'".chr($i)."'"; else $s.="chr($i)"; $s.='=>'.$fm['Widths'][$i]; if($i<255) $s.=','; if(($i+1)%22==0) $s.="\n\t"; } $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('<B>Error:</B> Can\'t 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) echo '<B>Warning:</B> font license does not allow embedding'; }
/******************************************************************************* * $fontfile : chemin du fichier TTF (ou chaîne vide si pas d'incorporation) * * $afmfile : chemin du fichier AFM * * $enc : encodage (ou chaîne vide si la police est symbolique) * * $patch : patch optionnel pour l'encodage * * $type : type de la police si $fontfile est vide * *******************************************************************************/ function MakeFont($fontfile,$afmfile,$enc='cp1252',$patch=array(),$type='TrueType') { //Generate a font definition file set_magic_quotes_runtime(0); ini_set('auto_detect_line_endings','1'); if($enc) { $map=ReadMap($enc); foreach($patch as $cc=>$gn) $map[$cc]=$gn; } else $map=array(); if(!file_exists($afmfile)) die('<B>Error:</B> AFM file not found: '.$afmfile); $fm=ReadAFM($afmfile,$map); if($enc) $diff=MakeFontEncoding($map); else $diff=''; $fd=MakeFontDescriptor($fm,empty($map)); //Find font type if($fontfile) { $ext=strtolower(substr($fontfile,-3)); if($ext=='ttf') $type='TrueType'; elseif($ext=='pfb') $type='Type1'; else die('<B>Error:</B> unrecognized font file extension: '.$ext); } else { if($type!='TrueType' and $type!='Type1') die('<B>Error:</B> incorrect font type: '.$type); } //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"; $w=MakeWidthArray($fm); $s.='$cw='.$w.";\n"; $s.='$enc=\''.$enc."';\n"; $s.='$diff=\''.$diff."';\n"; $basename=substr(basename($afmfile),0,-4); if($fontfile) { //Embedded font if(!file_exists($fontfile)) die('<B>Error:</B> font file not found: '.$fontfile); if($type=='TrueType') CheckTTF($fontfile); $f=fopen($fontfile,'rb'); if(!$f) die('<B>Error:</B> Can\'t 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('<B>Error:</B> 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('<B>Error:</B> font file does not seem to be valid Type1'); $size2=$pos-$size1; $file=substr($file,0,$size1+$size2); } if(function_exists('gzcompress')) { $cmp=$basename.'.z'; SaveToFile($cmp,gzcompress($file),'b'); $s.='$file=\''.$cmp."';\n"; echo 'Font file compressed ('.$cmp.')<BR>'; } else { $s.='$file=\''.basename($fontfile)."';\n"; echo '<B>Notice:</B> font file could not be compressed (zlib extension not available)<BR>'; } 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.="?>\n"; SaveToFile($basename.'.php',$s); echo 'Font definition file generated ('.$basename.'.php'.')<BR>'; } ?>
|