Functions

makefont.php File Reference

Go to the source code of this file.

Functions

 ReadMap ($enc)
 ReadAFM ($file, &$map)
 MakeFontDescriptor ($fm, $symbolic)
 MakeWidthArray ($fm)
 MakeFontEncoding ($map)
 SaveToFile ($file, $s, $mode)
 ReadShort ($f)
 ReadLong ($f)
 CheckTTF ($file)
 MakeFont ($fontfile, $afmfile, $enc='cp1252', $patch=array(), $type='TrueType')

Function Documentation

CheckTTF ( file  ) 

Definition at line 253 of file makefont.php.

References $file, $i, ReadLong(), and ReadShort().

Referenced by MakeFont().

{
    //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 && !$pp && !$e)
        echo '<b>Warning:</b> font license does not allow embedding';
}

MakeFont ( fontfile,
afmfile,
enc = 'cp1252',
patch = array(),
type = 'TrueType' 
)

Definition at line 300 of file makefont.php.

References $diff, $enc, $file, $header, $type, CheckTTF(), MakeFontDescriptor(), MakeFontEncoding(), MakeWidthArray(), ReadAFM(), ReadMap(), and SaveToFile().

{
    //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('<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' && $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 && 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,'t');
    echo 'Font definition file generated ('.$basename.'.php'.')<br>';
}

MakeFontDescriptor ( fm,
symbolic 
)

Definition at line 137 of file makefont.php.

References $desc.

Referenced by MakeFont().

{
    //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;
}

MakeFontEncoding ( map  ) 

Definition at line 213 of file makefont.php.

References $i, and ReadMap().

Referenced by MakeFont().

{
    //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);
}

MakeWidthArray ( fm  ) 

Definition at line 188 of file makefont.php.

References $cw, and $i.

Referenced by MakeFont().

{
    //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;
}

ReadAFM ( file,
&$  map 
)

Definition at line 36 of file makefont.php.

References $file, and $i.

Referenced by MakeFont().

{
    //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 '<b>Warning:</b> character '.$map[$i].' is missing<br>';
                $widths[$i]=$widths['.notdef'];
            }
            else
                $widths[$i]=$widths[$map[$i]];
        }
    }
    $fm['Widths']=$widths;
    return $fm;
}

ReadLong ( f  ) 

Definition at line 247 of file makefont.php.

Referenced by CheckTTF().

{
    $a=unpack('N1N',fread($f,4));
    return $a['N'];
}

ReadMap ( enc  ) 

Definition at line 10 of file makefont.php.

References $enc, $file, and $i.

Referenced by MakeFont(), and MakeFontEncoding().

{
    //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;
}

ReadShort ( f  ) 

Definition at line 241 of file makefont.php.

Referenced by CheckTTF().

{
    $a=unpack('n1n',fread($f,2));
    return $a['n'];
}

SaveToFile ( file,
s,
mode 
)

Definition at line 232 of file makefont.php.

References $file.

Referenced by MakeFont().

{
    $f=fopen($file,'w'.$mode);
    if(!$f)
        die('Can\'t write to file '.$file);
    fwrite($f,$s,strlen($s));
    fclose($f);
}

 All Data Structures Files Functions Variables Enumerations