00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010 function ReadMap($enc)
00011 {
00012
00013 $file=dirname(__FILE__).'/'.strtolower($enc).'.map';
00014 $a=file($file);
00015 if(empty($a))
00016 die('<b>Error:</b> encoding not found: '.$enc);
00017 $cc2gn=array();
00018 foreach($a as $l)
00019 {
00020 if($l[0]=='!')
00021 {
00022 $e=preg_split('/[ \\t]+/',rtrim($l));
00023 $cc=hexdec(substr($e[0],1));
00024 $gn=$e[2];
00025 $cc2gn[$cc]=$gn;
00026 }
00027 }
00028 for($i=0;$i<=255;$i++)
00029 {
00030 if(!isset($cc2gn[$i]))
00031 $cc2gn[$i]='.notdef';
00032 }
00033 return $cc2gn;
00034 }
00035
00036 function ReadAFM($file, &$map)
00037 {
00038
00039 $a=file($file);
00040 if(empty($a))
00041 die('File not found');
00042 $widths=array();
00043 $fm=array();
00044 $fix=array('Edot'=>'Edotaccent','edot'=>'edotaccent','Idot'=>'Idotaccent','Zdot'=>'Zdotaccent','zdot'=>'zdotaccent',
00045 'Odblacute'=>'Ohungarumlaut','odblacute'=>'ohungarumlaut','Udblacute'=>'Uhungarumlaut','udblacute'=>'uhungarumlaut',
00046 'Gcedilla'=>'Gcommaaccent','gcedilla'=>'gcommaaccent','Kcedilla'=>'Kcommaaccent','kcedilla'=>'kcommaaccent',
00047 'Lcedilla'=>'Lcommaaccent','lcedilla'=>'lcommaaccent','Ncedilla'=>'Ncommaaccent','ncedilla'=>'ncommaaccent',
00048 'Rcedilla'=>'Rcommaaccent','rcedilla'=>'rcommaaccent','Scedilla'=>'Scommaaccent','scedilla'=>'scommaaccent',
00049 'Tcedilla'=>'Tcommaaccent','tcedilla'=>'tcommaaccent','Dslash'=>'Dcroat','dslash'=>'dcroat','Dmacron'=>'Dcroat','dmacron'=>'dcroat',
00050 'combininggraveaccent'=>'gravecomb','combininghookabove'=>'hookabovecomb','combiningtildeaccent'=>'tildecomb',
00051 'combiningacuteaccent'=>'acutecomb','combiningdotbelow'=>'dotbelowcomb','dongsign'=>'dong');
00052 foreach($a as $l)
00053 {
00054 $e=explode(' ',rtrim($l));
00055 if(count($e)<2)
00056 continue;
00057 $code=$e[0];
00058 $param=$e[1];
00059 if($code=='C')
00060 {
00061
00062 $cc=(int)$e[1];
00063 $w=$e[4];
00064 $gn=$e[7];
00065 if(substr($gn,-4)=='20AC')
00066 $gn='Euro';
00067 if(isset($fix[$gn]))
00068 {
00069
00070 foreach($map as $c=>$n)
00071 {
00072 if($n==$fix[$gn])
00073 $map[$c]=$gn;
00074 }
00075 }
00076 if(empty($map))
00077 {
00078
00079 $widths[$cc]=$w;
00080 }
00081 else
00082 {
00083 $widths[$gn]=$w;
00084 if($gn=='X')
00085 $fm['CapXHeight']=$e[13];
00086 }
00087 if($gn=='.notdef')
00088 $fm['MissingWidth']=$w;
00089 }
00090 elseif($code=='FontName')
00091 $fm['FontName']=$param;
00092 elseif($code=='Weight')
00093 $fm['Weight']=$param;
00094 elseif($code=='ItalicAngle')
00095 $fm['ItalicAngle']=(double)$param;
00096 elseif($code=='Ascender')
00097 $fm['Ascender']=(int)$param;
00098 elseif($code=='Descender')
00099 $fm['Descender']=(int)$param;
00100 elseif($code=='UnderlineThickness')
00101 $fm['UnderlineThickness']=(int)$param;
00102 elseif($code=='UnderlinePosition')
00103 $fm['UnderlinePosition']=(int)$param;
00104 elseif($code=='IsFixedPitch')
00105 $fm['IsFixedPitch']=($param=='true');
00106 elseif($code=='FontBBox')
00107 $fm['FontBBox']=array($e[1],$e[2],$e[3],$e[4]);
00108 elseif($code=='CapHeight')
00109 $fm['CapHeight']=(int)$param;
00110 elseif($code=='StdVW')
00111 $fm['StdVW']=(int)$param;
00112 }
00113 if(!isset($fm['FontName']))
00114 die('FontName not found');
00115 if(!empty($map))
00116 {
00117 if(!isset($widths['.notdef']))
00118 $widths['.notdef']=600;
00119 if(!isset($widths['Delta']) && isset($widths['increment']))
00120 $widths['Delta']=$widths['increment'];
00121
00122 for($i=0;$i<=255;$i++)
00123 {
00124 if(!isset($widths[$map[$i]]))
00125 {
00126 echo '<b>Warning:</b> character '.$map[$i].' is missing<br>';
00127 $widths[$i]=$widths['.notdef'];
00128 }
00129 else
00130 $widths[$i]=$widths[$map[$i]];
00131 }
00132 }
00133 $fm['Widths']=$widths;
00134 return $fm;
00135 }
00136
00137 function MakeFontDescriptor($fm, $symbolic)
00138 {
00139
00140 $asc=(isset($fm['Ascender']) ? $fm['Ascender'] : 1000);
00141 $fd="array('Ascent'=>".$asc;
00142
00143 $desc=(isset($fm['Descender']) ? $fm['Descender'] : -200);
00144 $fd.=",'Descent'=>".$desc;
00145
00146 if(isset($fm['CapHeight']))
00147 $ch=$fm['CapHeight'];
00148 elseif(isset($fm['CapXHeight']))
00149 $ch=$fm['CapXHeight'];
00150 else
00151 $ch=$asc;
00152 $fd.=",'CapHeight'=>".$ch;
00153
00154 $flags=0;
00155 if(isset($fm['IsFixedPitch']) && $fm['IsFixedPitch'])
00156 $flags+=1<<0;
00157 if($symbolic)
00158 $flags+=1<<2;
00159 if(!$symbolic)
00160 $flags+=1<<5;
00161 if(isset($fm['ItalicAngle']) && $fm['ItalicAngle']!=0)
00162 $flags+=1<<6;
00163 $fd.=",'Flags'=>".$flags;
00164
00165 if(isset($fm['FontBBox']))
00166 $fbb=$fm['FontBBox'];
00167 else
00168 $fbb=array(0,$desc-100,1000,$asc+100);
00169 $fd.=",'FontBBox'=>'[".$fbb[0].' '.$fbb[1].' '.$fbb[2].' '.$fbb[3]."]'";
00170
00171 $ia=(isset($fm['ItalicAngle']) ? $fm['ItalicAngle'] : 0);
00172 $fd.=",'ItalicAngle'=>".$ia;
00173
00174 if(isset($fm['StdVW']))
00175 $stemv=$fm['StdVW'];
00176 elseif(isset($fm['Weight']) && preg_match('/bold|black/i',$fm['Weight']))
00177 $stemv=120;
00178 else
00179 $stemv=70;
00180 $fd.=",'StemV'=>".$stemv;
00181
00182 if(isset($fm['MissingWidth']))
00183 $fd.=",'MissingWidth'=>".$fm['MissingWidth'];
00184 $fd.=')';
00185 return $fd;
00186 }
00187
00188 function MakeWidthArray($fm)
00189 {
00190
00191 $s="array(\n\t";
00192 $cw=$fm['Widths'];
00193 for($i=0;$i<=255;$i++)
00194 {
00195 if(chr($i)=="'")
00196 $s.="'\\''";
00197 elseif(chr($i)=="\\")
00198 $s.="'\\\\'";
00199 elseif($i>=32 && $i<=126)
00200 $s.="'".chr($i)."'";
00201 else
00202 $s.="chr($i)";
00203 $s.='=>'.$fm['Widths'][$i];
00204 if($i<255)
00205 $s.=',';
00206 if(($i+1)%22==0)
00207 $s.="\n\t";
00208 }
00209 $s.=')';
00210 return $s;
00211 }
00212
00213 function MakeFontEncoding($map)
00214 {
00215
00216 $ref=ReadMap('cp1252');
00217 $s='';
00218 $last=0;
00219 for($i=32;$i<=255;$i++)
00220 {
00221 if($map[$i]!=$ref[$i])
00222 {
00223 if($i!=$last+1)
00224 $s.=$i.' ';
00225 $last=$i;
00226 $s.='/'.$map[$i].' ';
00227 }
00228 }
00229 return rtrim($s);
00230 }
00231
00232 function SaveToFile($file, $s, $mode)
00233 {
00234 $f=fopen($file,'w'.$mode);
00235 if(!$f)
00236 die('Can\'t write to file '.$file);
00237 fwrite($f,$s,strlen($s));
00238 fclose($f);
00239 }
00240
00241 function ReadShort($f)
00242 {
00243 $a=unpack('n1n',fread($f,2));
00244 return $a['n'];
00245 }
00246
00247 function ReadLong($f)
00248 {
00249 $a=unpack('N1N',fread($f,4));
00250 return $a['N'];
00251 }
00252
00253 function CheckTTF($file)
00254 {
00255
00256 $f=fopen($file,'rb');
00257 if(!$f)
00258 die('<b>Error:</b> Can\'t open '.$file);
00259
00260 fseek($f,4,SEEK_CUR);
00261 $nb=ReadShort($f);
00262 fseek($f,6,SEEK_CUR);
00263
00264 $found=false;
00265 for($i=0;$i<$nb;$i++)
00266 {
00267 if(fread($f,4)=='OS/2')
00268 {
00269 $found=true;
00270 break;
00271 }
00272 fseek($f,12,SEEK_CUR);
00273 }
00274 if(!$found)
00275 {
00276 fclose($f);
00277 return;
00278 }
00279 fseek($f,4,SEEK_CUR);
00280 $offset=ReadLong($f);
00281 fseek($f,$offset,SEEK_SET);
00282
00283 fseek($f,8,SEEK_CUR);
00284 $fsType=ReadShort($f);
00285 $rl=($fsType & 0x02)!=0;
00286 $pp=($fsType & 0x04)!=0;
00287 $e=($fsType & 0x08)!=0;
00288 fclose($f);
00289 if($rl && !$pp && !$e)
00290 echo '<b>Warning:</b> font license does not allow embedding';
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300 function MakeFont($fontfile, $afmfile, $enc='cp1252', $patch=array(), $type='TrueType')
00301 {
00302
00303 if(get_magic_quotes_runtime())
00304 @set_magic_quotes_runtime(0);
00305 ini_set('auto_detect_line_endings','1');
00306 if($enc)
00307 {
00308 $map=ReadMap($enc);
00309 foreach($patch as $cc=>$gn)
00310 $map[$cc]=$gn;
00311 }
00312 else
00313 $map=array();
00314 if(!file_exists($afmfile))
00315 die('<b>Error:</b> AFM file not found: '.$afmfile);
00316 $fm=ReadAFM($afmfile,$map);
00317 if($enc)
00318 $diff=MakeFontEncoding($map);
00319 else
00320 $diff='';
00321 $fd=MakeFontDescriptor($fm,empty($map));
00322
00323 if($fontfile)
00324 {
00325 $ext=strtolower(substr($fontfile,-3));
00326 if($ext=='ttf')
00327 $type='TrueType';
00328 elseif($ext=='pfb')
00329 $type='Type1';
00330 else
00331 die('<b>Error:</b> unrecognized font file extension: '.$ext);
00332 }
00333 else
00334 {
00335 if($type!='TrueType' && $type!='Type1')
00336 die('<b>Error:</b> incorrect font type: '.$type);
00337 }
00338
00339 $s='<?php'."\n";
00340 $s.='$type=\''.$type."';\n";
00341 $s.='$name=\''.$fm['FontName']."';\n";
00342 $s.='$desc='.$fd.";\n";
00343 if(!isset($fm['UnderlinePosition']))
00344 $fm['UnderlinePosition']=-100;
00345 if(!isset($fm['UnderlineThickness']))
00346 $fm['UnderlineThickness']=50;
00347 $s.='$up='.$fm['UnderlinePosition'].";\n";
00348 $s.='$ut='.$fm['UnderlineThickness'].";\n";
00349 $w=MakeWidthArray($fm);
00350 $s.='$cw='.$w.";\n";
00351 $s.='$enc=\''.$enc."';\n";
00352 $s.='$diff=\''.$diff."';\n";
00353 $basename=substr(basename($afmfile),0,-4);
00354 if($fontfile)
00355 {
00356
00357 if(!file_exists($fontfile))
00358 die('<b>Error:</b> font file not found: '.$fontfile);
00359 if($type=='TrueType')
00360 CheckTTF($fontfile);
00361 $f=fopen($fontfile,'rb');
00362 if(!$f)
00363 die('<b>Error:</b> Can\'t open '.$fontfile);
00364 $file=fread($f,filesize($fontfile));
00365 fclose($f);
00366 if($type=='Type1')
00367 {
00368
00369 $header=(ord($file[0])==128);
00370 if($header)
00371 {
00372
00373 $file=substr($file,6);
00374 }
00375 $pos=strpos($file,'eexec');
00376 if(!$pos)
00377 die('<b>Error:</b> font file does not seem to be valid Type1');
00378 $size1=$pos+6;
00379 if($header && ord($file[$size1])==128)
00380 {
00381
00382 $file=substr($file,0,$size1).substr($file,$size1+6);
00383 }
00384 $pos=strpos($file,'00000000');
00385 if(!$pos)
00386 die('<b>Error:</b> font file does not seem to be valid Type1');
00387 $size2=$pos-$size1;
00388 $file=substr($file,0,$size1+$size2);
00389 }
00390 if(function_exists('gzcompress'))
00391 {
00392 $cmp=$basename.'.z';
00393 SaveToFile($cmp,gzcompress($file),'b');
00394 $s.='$file=\''.$cmp."';\n";
00395 echo 'Font file compressed ('.$cmp.')<br>';
00396 }
00397 else
00398 {
00399 $s.='$file=\''.basename($fontfile)."';\n";
00400 echo '<b>Notice:</b> font file could not be compressed (zlib extension not available)<br>';
00401 }
00402 if($type=='Type1')
00403 {
00404 $s.='$size1='.$size1.";\n";
00405 $s.='$size2='.$size2.";\n";
00406 }
00407 else
00408 $s.='$originalsize='.filesize($fontfile).";\n";
00409 }
00410 else
00411 {
00412
00413 $s.='$file='."'';\n";
00414 }
00415 $s.="?>\n";
00416 SaveToFile($basename.'.php',$s,'t');
00417 echo 'Font definition file generated ('.$basename.'.php'.')<br>';
00418 }
00419 ?>