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; } 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']) && isset($widths['increment'])) { $widths['Delta']=$widths['increment']; } //Order widths according to map for ($i=0;$i<=255;$i++) { if (!isset($widths[$map[$i]])) { echo 'Warning: character '.$map[$i].' is missing
'; $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']) && $fm['IsFixedPitch']) { $flags+=1<<0; } if ($symbolic) { $flags+=1<<2; } if (!$symbolic) { $flags+=1<<5; } if (isset($fm['ItalicAngle']) && $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']) && 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(\n\t"; $cw=$fm['Widths']; for ($i=0;$i<=255;$i++) { if (chr($i)=="'") { $s.="'\\''"; } elseif (chr($i)=="\\") { $s.="'\\\\'"; } elseif ($i>=32 && $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) { $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: 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 && !$pp && !$e) { echo 'Warning: font license does not allow embedding'; } } /******************************************************************************* * fontfile: path to TTF file (or empty string if not to be embedded) * * afmfile: path to AFM file * * enc: font encoding (or empty string for symbolic fonts) * * patch: optional patch for encoding * * type: font type if fontfile is empty * *******************************************************************************/ function MakeFont($fontfile, $afmfile, $enc='cp1252', $patch=array(), $type='TrueType') { //Generate a font definition file if (get_magic_quotes_runtime()) { @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('Error: 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('Error: unrecognized font file extension: '.$ext); } } else { if ($type!='TrueType' && $type!='Type1') { die('Error: incorrect font type: '.$type); } } //Start generation $s='Error: font file not found: '.$fontfile); } if ($type=='TrueType') { CheckTTF($fontfile); } $f=fopen($fontfile, 'rb'); if (!$f) { die('Error: 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('Error: font file does not seem to be valid Type1'); } $size1=$pos+6; if ($header && 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); } if (function_exists('gzcompress')) { $cmp=$basename.'.z'; SaveToFile($cmp, gzcompress($file), 'b'); $s.='$file=\''.$cmp."';\n"; echo 'Font file compressed ('.$cmp.')
'; } else { $s.='$file=\''.basename($fontfile)."';\n"; echo 'Notice: font file could not be compressed (zlib extension not available)
'; } 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, 't'); echo 'Font definition file generated ('.$basename.'.php'.')
'; }