PHP:如何阅读“标题” .ttf 文件中的字体?

发布于 2024-11-01 05:13:17 字数 269 浏览 0 评论 0原文

我确实需要能够从 .ttf true type 字体文件中提取元数据。

我正在建立一个中央数据库,其中包含我们所有设计师使用的所有字体(他们永远通过电子邮件交换字体以接管设计元素等)。我想获取所有字体,有些字体有愚蠢的名称,如 00001.ttf,所以文件名没有帮助,但我知道字体有元数据,我需要某种方法在 PHP 中提取它。

然后我可以创建一个循环来查看我指定的目录,获取此数据(以及我可以同时获取的任何其他数据),并将其添加到数据库中。

我真的需要帮助来读取此元数据部分。

I really need to be able to extract the metadata from a .ttf true type font file.

I'm building a central database of all the fonts all our designers use (they're forever swapping fonts via email to take over design elements, etc). I want to get all the fonts, some have silly names like 00001.ttf, so file name is no help, but I know the fonts have metadata, I need some way to extract that in PHP.

Then I can create a loop to look through the directories I've specified, get this data (and any other data I can get at the same time, and add it to a database.

I just really need help with the reading of this metadata part.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谜兔 2024-11-08 05:13:17

我遇到了此链接。它会做你想做的事(我已经测试过并发布结果)。只需将要从中解析数据的 TTF 文件的路径传递给类即可。然后使用$fontinfo[1]。' '.$fontinfo[2] 为名称。

如果您不想注册,这里是类

结果数据

Array
(
    [1] => Almonte Snow
    [2] => Regular
    [3] => RayLarabie: Almonte Snow: 2000
    [4] => Almonte Snow
    [5] => Version 2.000 2004
    [6] => AlmonteSnow
    [8] => Ray Larabie
    [9] => Ray Larabie
    [10] => Larabie Fonts is able to offer unique free fonts through the generous support of visitors to the site. Making fonts is my full-time job and every donation, in any amount, enables me to continue running the site and creating new fonts. If you would like to support Larabie Fonts visit www.larabiefonts.com for details.
    [11] => http://www.larabiefonts.com
    [12] => http://www.typodermic.com
)

使用

<?php 
    include 'ttfInfo.class.php'; 
    $fontinfo = getFontInfo('c:\windows\fonts\_LDS_almosnow.ttf'); 
    echo '<pre>'; 
    print_r($fontinfo); 
    echo '</pre>'; 
?>

ttfInfo.class.php

<?php 
/** 
 * ttfInfo class 
 * Retrieve data stored in a TTF files 'name' table 
 * 
 * @original author Unknown 
 * found at http://www.phpclasses.org/browse/package/2144.html 
 * 
 * @ported for used on http://www.nufont.com 
 * @author Jason Arencibia 
 * @version 0.2 
 * @copyright (c) 2006 GrayTap Media 
 * @website http://www.graytap.com 
 * @license GPL 2.0 
 * @access public 
 * 
 * @todo: Make it Retrieve additional information from other tables 
 *  
 */ 
class ttfInfo { 
    /** 
    * variable $_dirRestriction 
    * Restrict the resource pointer to this directory and above. 
    * Change to 1 for to allow the class to look outside of it current directory 
    * @protected 
    * @var int 
    */ 
    protected $_dirRestriction = 1; 
    /** 
    * variable $_dirRestriction 
    * Restrict the resource pointer to this directory and above. 
    * Change to 1 for nested directories 
    * @protected 
    * @var int 
    */ 
    protected $_recursive = 0; 

    /** 
    * variable $fontsdir 
    * This is to declare this variable as protected 
    * don't edit this!!! 
    * @protected 
    */ 
    protected $fontsdir; 
    /** 
    * variable $filename 
    * This is to declare this varable as protected 
    * don't edit this!!! 
    * @protected 
    */ 
    protected $filename; 

    /** 
    * function setFontFile() 
    * set the filename 
    * @public 
    * @param string $data the new value 
    * @return object reference to this 
    */ 
    public function setFontFile($data) 
    { 
        if ($this->_dirRestriction && preg_match('[\.\/|\.\.\/]', $data)) 
        { 
            $this->exitClass('Error: Directory restriction is enforced!'); 
        } 

        $this->filename = $data; 
        return $this; 
    } // public function setFontFile 

    /** 
    * function setFontsDir() 
    * set the Font Directory 
    * @public 
    * @param string $data the new value 
    * @return object referrence to this 
    */ 
    public function setFontsDir($data) 
    { 
        if ($this->_dirRestriction && preg_match('[\.\/|\.\.\/]', $data)) 
        { 
            $this->exitClass('Error: Directory restriction is enforced!'); 
        } 

        $this->fontsdir = $data; 
        return $this; 
    } // public function setFontsDir 

    /** 
    * function readFontsDir()  
    * @public 
    * @return information contained in the TTF 'name' table of all fonts in a directory. 
    */ 
    public function readFontsDir() 
    { 
        if (empty($this->fontsdir)) { $this->exitClass('Error: Fonts Directory has not been set with setFontsDir().'); } 
        if (empty($this->backupDir)){ $this->backupDir = $this->fontsdir; } 

        $this->array = array(); 
        $d = dir($this->fontsdir); 

        while (false !== ($e = $d->read())) 
        { 
            if($e != '.' && $e != '..') 
            { 
                $e = $this->fontsdir . $e; 
                if($this->_recursive && is_dir($e)) 
                { 
                    $this->setFontsDir($e); 
                    $this->array = array_merge($this->array, readFontsDir()); 
                } 
                else if ($this->is_ttf($e) === true) 
                { 
                    $this->setFontFile($e); 
                    $this->array[$e] = $this->getFontInfo(); 
                } 
            } 
        } 

        if (!empty($this->backupDir)){ $this->fontsdir = $this->backupDir; } 

        $d->close(); 
        return $this; 
    } // public function readFontsDir 

    /** 
    * function setProtectedVar() 
    * @public 
    * @param string $var the new variable 
    * @param string $data the new value 
    * @return object reference to this 

    * DISABLED, NO REAL USE YET 

    public function setProtectedVar($var, $data) 
    { 
        if ($var == 'filename') 
        { 
            $this->setFontFile($data); 
        } else { 
            //if (isset($var) && !empty($data)) 
            $this->$var = $data; 
        } 
        return $this; 
    } 
    */ 
    /** 
    * function getFontInfo()  
    * @public 
    * @return information contained in the TTF 'name' table. 
    */ 
    public function getFontInfo() 
    { 
        $fd = fopen ($this->filename, "r"); 
        $this->text = fread ($fd, filesize($this->filename)); 
        fclose ($fd); 

        $number_of_tables = hexdec($this->dec2ord($this->text[4]).$this->dec2ord($this->text[5])); 

        for ($i=0;$i<$number_of_tables;$i++) 
        { 
            $tag = $this->text[12+$i*16].$this->text[12+$i*16+1].$this->text[12+$i*16+2].$this->text[12+$i*16+3];

            if ($tag == 'name') 
            { 
                $this->ntOffset = hexdec( 
                    $this->dec2ord($this->text[12+$i*16+8]).$this->dec2ord($this->text[12+$i*16+8+1]). 
                    $this->dec2ord($this->text[12+$i*16+8+2]).$this->dec2ord($this->text[12+$i*16+8+3])); 

                $offset_storage_dec = hexdec($this->dec2ord($this->text[$this->ntOffset+4]).$this->dec2ord($this->text[$this->ntOffset+5])); 
                $number_name_records_dec = hexdec($this->dec2ord($this->text[$this->ntOffset+2]).$this->dec2ord($this->text[$this->ntOffset+3])); 
            } 
        } 

        $storage_dec = $offset_storage_dec + $this->ntOffset; 
        $storage_hex = strtoupper(dechex($storage_dec)); 

        for ($j=0;$j<$number_name_records_dec;$j++) 
        { 
            $platform_id_dec    = hexdec($this->dec2ord($this->text[$this->ntOffset+6+$j*12+0]).$this->dec2ord($this->text[$this->ntOffset+6+$j*12+1])); 
            $name_id_dec        = hexdec($this->dec2ord($this->text[$this->ntOffset+6+$j*12+6]).$this->dec2ord($this->text[$this->ntOffset+6+$j*12+7])); 
            $string_length_dec    = hexdec($this->dec2ord($this->text[$this->ntOffset+6+$j*12+8]).$this->dec2ord($this->text[$this->ntOffset+6+$j*12+9])); 
            $string_offset_dec    = hexdec($this->dec2ord($this->text[$this->ntOffset+6+$j*12+10]).$this->dec2ord($this->text[$this->ntOffset+6+$j*12+11])); 

            if (!empty($name_id_dec) and empty($font_tags[$name_id_dec])) 
            { 
                for($l=0;$l<$string_length_dec;$l++) 
                { 
                    if (ord($this->text[$storage_dec+$string_offset_dec+$l]) == '0') { continue; } 
                    else { $font_tags[$name_id_dec] .= ($this->text[$storage_dec+$string_offset_dec+$l]); } 
                } 
            } 
        } 
        return $font_tags; 
    } // public function getFontInfo 

    /** 
    * function getCopyright()  
    * @public 
    * @return 'Copyright notice' contained in the TTF 'name' table at index 0 
    */ 
    public function getCopyright() 
    { 
        $this->info = $this->getFontInfo(); 
        return $this->info[0]; 
    } // public function getCopyright 

    /** 
    * function getFontFamily()  
    * @public 
    * @return 'Font Family name' contained in the TTF 'name' table at index 1 
    */ 
    public function getFontFamily() 
    { 
        $this->info = $this->getFontInfo(); 
        return $this->info[1]; 
    } // public function getFontFamily 

    /** 
    * function getFontSubFamily()  
    * @public 
    * @return 'Font Subfamily name' contained in the TTF 'name' table at index 2 
    */ 
    public function getFontSubFamily() 
    { 
        $this->info = $this->getFontInfo(); 
        return $this->info[2]; 
    } // public function getFontSubFamily 

    /** 
    * function getFontId()  
    * @public 
    * @return 'Unique font identifier' contained in the TTF 'name' table at index 3 
    */ 
    public function getFontId() 
    { 
        $this->info = $this->getFontInfo(); 
        return $this->info[3]; 
    } // public function getFontId 

    /** 
    * function getFullFontName()  
    * @public 
    * @return 'Full font name' contained in the TTF 'name' table at index 4 
    */ 
    public function getFullFontName() 
    { 
        $this->info = $this->getFontInfo(); 
        return $this->info[4]; 
    } // public function getFullFontName 

    /** 
    * function dec2ord() 
    * Used to lessen redundant calls to multiple functions. 
    * @protected 
    * @return object 
    */ 
    protected function dec2ord($dec) 
    { 
        return $this->dec2hex(ord($dec)); 
    } // protected function dec2ord 

    /** 
    * function dec2hex() 
    * private function to perform Hexadecimal to decimal with proper padding. 
    * @protected 
    * @return object 
    */ 
    protected function dec2hex($dec) 
    { 
        return str_repeat('0', 2-strlen(($hex=strtoupper(dechex($dec))))) . $hex; 
    } // protected function dec2hex 

    /** 
    * function dec2hex() 
    * private function to perform Hexadecimal to decimal with proper padding. 
    * @protected 
    * @return object 
    */ 
    protected function exitClass($message) 
    { 
        echo $message; 
        exit; 
    } // protected function dec2hex 

    /** 
    * function dec2hex() 
    * private helper function to test in the file in question is a ttf. 
    * @protected 
    * @return object 
    */ 
    protected function is_ttf($file) 
    { 
        $ext = explode('.', $file); 
        $ext = $ext[count($ext)-1]; 
        return preg_match("/ttf$/i",$ext) ? true : false; 
    } // protected function is_ttf 
} // class ttfInfo 

function getFontInfo($resource) 
{ 
    $ttfInfo = new ttfInfo; 
    $ttfInfo->setFontFile($resource); 
    return $ttfInfo->getFontInfo(); 
} 
?>

2021 更新

这里是更新版本类的一些修复
https://github.com/Husamaamer/TTFInfo.git

I came across this link. It will do what you want (I've tested it and posted results). Just pass the class the path of the TTF file you want to parse the data out of. then use $fontinfo[1].' '.$fontinfo[2] for the name.

In case you don't want to register, here is the class

Resulting Data

Array
(
    [1] => Almonte Snow
    [2] => Regular
    [3] => RayLarabie: Almonte Snow: 2000
    [4] => Almonte Snow
    [5] => Version 2.000 2004
    [6] => AlmonteSnow
    [8] => Ray Larabie
    [9] => Ray Larabie
    [10] => Larabie Fonts is able to offer unique free fonts through the generous support of visitors to the site. Making fonts is my full-time job and every donation, in any amount, enables me to continue running the site and creating new fonts. If you would like to support Larabie Fonts visit www.larabiefonts.com for details.
    [11] => http://www.larabiefonts.com
    [12] => http://www.typodermic.com
)

Usage

<?php 
    include 'ttfInfo.class.php'; 
    $fontinfo = getFontInfo('c:\windows\fonts\_LDS_almosnow.ttf'); 
    echo '<pre>'; 
    print_r($fontinfo); 
    echo '</pre>'; 
?>

ttfInfo.class.php

<?php 
/** 
 * ttfInfo class 
 * Retrieve data stored in a TTF files 'name' table 
 * 
 * @original author Unknown 
 * found at http://www.phpclasses.org/browse/package/2144.html 
 * 
 * @ported for used on http://www.nufont.com 
 * @author Jason Arencibia 
 * @version 0.2 
 * @copyright (c) 2006 GrayTap Media 
 * @website http://www.graytap.com 
 * @license GPL 2.0 
 * @access public 
 * 
 * @todo: Make it Retrieve additional information from other tables 
 *  
 */ 
class ttfInfo { 
    /** 
    * variable $_dirRestriction 
    * Restrict the resource pointer to this directory and above. 
    * Change to 1 for to allow the class to look outside of it current directory 
    * @protected 
    * @var int 
    */ 
    protected $_dirRestriction = 1; 
    /** 
    * variable $_dirRestriction 
    * Restrict the resource pointer to this directory and above. 
    * Change to 1 for nested directories 
    * @protected 
    * @var int 
    */ 
    protected $_recursive = 0; 

    /** 
    * variable $fontsdir 
    * This is to declare this variable as protected 
    * don't edit this!!! 
    * @protected 
    */ 
    protected $fontsdir; 
    /** 
    * variable $filename 
    * This is to declare this varable as protected 
    * don't edit this!!! 
    * @protected 
    */ 
    protected $filename; 

    /** 
    * function setFontFile() 
    * set the filename 
    * @public 
    * @param string $data the new value 
    * @return object reference to this 
    */ 
    public function setFontFile($data) 
    { 
        if ($this->_dirRestriction && preg_match('[\.\/|\.\.\/]', $data)) 
        { 
            $this->exitClass('Error: Directory restriction is enforced!'); 
        } 

        $this->filename = $data; 
        return $this; 
    } // public function setFontFile 

    /** 
    * function setFontsDir() 
    * set the Font Directory 
    * @public 
    * @param string $data the new value 
    * @return object referrence to this 
    */ 
    public function setFontsDir($data) 
    { 
        if ($this->_dirRestriction && preg_match('[\.\/|\.\.\/]', $data)) 
        { 
            $this->exitClass('Error: Directory restriction is enforced!'); 
        } 

        $this->fontsdir = $data; 
        return $this; 
    } // public function setFontsDir 

    /** 
    * function readFontsDir()  
    * @public 
    * @return information contained in the TTF 'name' table of all fonts in a directory. 
    */ 
    public function readFontsDir() 
    { 
        if (empty($this->fontsdir)) { $this->exitClass('Error: Fonts Directory has not been set with setFontsDir().'); } 
        if (empty($this->backupDir)){ $this->backupDir = $this->fontsdir; } 

        $this->array = array(); 
        $d = dir($this->fontsdir); 

        while (false !== ($e = $d->read())) 
        { 
            if($e != '.' && $e != '..') 
            { 
                $e = $this->fontsdir . $e; 
                if($this->_recursive && is_dir($e)) 
                { 
                    $this->setFontsDir($e); 
                    $this->array = array_merge($this->array, readFontsDir()); 
                } 
                else if ($this->is_ttf($e) === true) 
                { 
                    $this->setFontFile($e); 
                    $this->array[$e] = $this->getFontInfo(); 
                } 
            } 
        } 

        if (!empty($this->backupDir)){ $this->fontsdir = $this->backupDir; } 

        $d->close(); 
        return $this; 
    } // public function readFontsDir 

    /** 
    * function setProtectedVar() 
    * @public 
    * @param string $var the new variable 
    * @param string $data the new value 
    * @return object reference to this 

    * DISABLED, NO REAL USE YET 

    public function setProtectedVar($var, $data) 
    { 
        if ($var == 'filename') 
        { 
            $this->setFontFile($data); 
        } else { 
            //if (isset($var) && !empty($data)) 
            $this->$var = $data; 
        } 
        return $this; 
    } 
    */ 
    /** 
    * function getFontInfo()  
    * @public 
    * @return information contained in the TTF 'name' table. 
    */ 
    public function getFontInfo() 
    { 
        $fd = fopen ($this->filename, "r"); 
        $this->text = fread ($fd, filesize($this->filename)); 
        fclose ($fd); 

        $number_of_tables = hexdec($this->dec2ord($this->text[4]).$this->dec2ord($this->text[5])); 

        for ($i=0;$i<$number_of_tables;$i++) 
        { 
            $tag = $this->text[12+$i*16].$this->text[12+$i*16+1].$this->text[12+$i*16+2].$this->text[12+$i*16+3];

            if ($tag == 'name') 
            { 
                $this->ntOffset = hexdec( 
                    $this->dec2ord($this->text[12+$i*16+8]).$this->dec2ord($this->text[12+$i*16+8+1]). 
                    $this->dec2ord($this->text[12+$i*16+8+2]).$this->dec2ord($this->text[12+$i*16+8+3])); 

                $offset_storage_dec = hexdec($this->dec2ord($this->text[$this->ntOffset+4]).$this->dec2ord($this->text[$this->ntOffset+5])); 
                $number_name_records_dec = hexdec($this->dec2ord($this->text[$this->ntOffset+2]).$this->dec2ord($this->text[$this->ntOffset+3])); 
            } 
        } 

        $storage_dec = $offset_storage_dec + $this->ntOffset; 
        $storage_hex = strtoupper(dechex($storage_dec)); 

        for ($j=0;$j<$number_name_records_dec;$j++) 
        { 
            $platform_id_dec    = hexdec($this->dec2ord($this->text[$this->ntOffset+6+$j*12+0]).$this->dec2ord($this->text[$this->ntOffset+6+$j*12+1])); 
            $name_id_dec        = hexdec($this->dec2ord($this->text[$this->ntOffset+6+$j*12+6]).$this->dec2ord($this->text[$this->ntOffset+6+$j*12+7])); 
            $string_length_dec    = hexdec($this->dec2ord($this->text[$this->ntOffset+6+$j*12+8]).$this->dec2ord($this->text[$this->ntOffset+6+$j*12+9])); 
            $string_offset_dec    = hexdec($this->dec2ord($this->text[$this->ntOffset+6+$j*12+10]).$this->dec2ord($this->text[$this->ntOffset+6+$j*12+11])); 

            if (!empty($name_id_dec) and empty($font_tags[$name_id_dec])) 
            { 
                for($l=0;$l<$string_length_dec;$l++) 
                { 
                    if (ord($this->text[$storage_dec+$string_offset_dec+$l]) == '0') { continue; } 
                    else { $font_tags[$name_id_dec] .= ($this->text[$storage_dec+$string_offset_dec+$l]); } 
                } 
            } 
        } 
        return $font_tags; 
    } // public function getFontInfo 

    /** 
    * function getCopyright()  
    * @public 
    * @return 'Copyright notice' contained in the TTF 'name' table at index 0 
    */ 
    public function getCopyright() 
    { 
        $this->info = $this->getFontInfo(); 
        return $this->info[0]; 
    } // public function getCopyright 

    /** 
    * function getFontFamily()  
    * @public 
    * @return 'Font Family name' contained in the TTF 'name' table at index 1 
    */ 
    public function getFontFamily() 
    { 
        $this->info = $this->getFontInfo(); 
        return $this->info[1]; 
    } // public function getFontFamily 

    /** 
    * function getFontSubFamily()  
    * @public 
    * @return 'Font Subfamily name' contained in the TTF 'name' table at index 2 
    */ 
    public function getFontSubFamily() 
    { 
        $this->info = $this->getFontInfo(); 
        return $this->info[2]; 
    } // public function getFontSubFamily 

    /** 
    * function getFontId()  
    * @public 
    * @return 'Unique font identifier' contained in the TTF 'name' table at index 3 
    */ 
    public function getFontId() 
    { 
        $this->info = $this->getFontInfo(); 
        return $this->info[3]; 
    } // public function getFontId 

    /** 
    * function getFullFontName()  
    * @public 
    * @return 'Full font name' contained in the TTF 'name' table at index 4 
    */ 
    public function getFullFontName() 
    { 
        $this->info = $this->getFontInfo(); 
        return $this->info[4]; 
    } // public function getFullFontName 

    /** 
    * function dec2ord() 
    * Used to lessen redundant calls to multiple functions. 
    * @protected 
    * @return object 
    */ 
    protected function dec2ord($dec) 
    { 
        return $this->dec2hex(ord($dec)); 
    } // protected function dec2ord 

    /** 
    * function dec2hex() 
    * private function to perform Hexadecimal to decimal with proper padding. 
    * @protected 
    * @return object 
    */ 
    protected function dec2hex($dec) 
    { 
        return str_repeat('0', 2-strlen(($hex=strtoupper(dechex($dec))))) . $hex; 
    } // protected function dec2hex 

    /** 
    * function dec2hex() 
    * private function to perform Hexadecimal to decimal with proper padding. 
    * @protected 
    * @return object 
    */ 
    protected function exitClass($message) 
    { 
        echo $message; 
        exit; 
    } // protected function dec2hex 

    /** 
    * function dec2hex() 
    * private helper function to test in the file in question is a ttf. 
    * @protected 
    * @return object 
    */ 
    protected function is_ttf($file) 
    { 
        $ext = explode('.', $file); 
        $ext = $ext[count($ext)-1]; 
        return preg_match("/ttf$/i",$ext) ? true : false; 
    } // protected function is_ttf 
} // class ttfInfo 

function getFontInfo($resource) 
{ 
    $ttfInfo = new ttfInfo; 
    $ttfInfo->setFontFile($resource); 
    return $ttfInfo->getFontInfo(); 
} 
?>

Update 2021

Here is an updated version of the class with some fixes
https://github.com/HusamAamer/TTFInfo.git

姜生凉生 2024-11-08 05:13:17

与之前发布的答案非常相似...我已经使用这个类很长时间了。

class fontAttributes extends baseClass
{
    // --- ATTRIBUTES ---

    /**
     *  @access private
     *  @var string
     */
    private $_fileName          = NULL ;                    //  Name of the truetype font file


    /**
     *  @access private
     *  @var string
     */
    private $_copyright         = NULL ;                    //  Copyright


    /**
     *  @access private
     *  @var string
     */
    private $_fontFamily        = NULL ;                    //  Font Family


    /**
     *  @access private
     *  @var string
     */
    private $_fontSubFamily     = NULL ;                    //  Font SubFamily


    /**
     *  @access private
     *  @var string
     */
    private $_fontIdentifier    = NULL ;                    //  Font Unique Identifier


    /**
     *  @access private
     *  @var string
     */
    private $_fontName          = NULL ;                    //  Font Name


    /**
     *  @access private
     *  @var string
     */
    private $_fontVersion       = NULL ;                    //  Font Version


    /**
     *  @access private
     *  @var string
     */
    private $_postscriptName    = NULL ;                    //  Postscript Name


    /**
     *  @access private
     *  @var string
     */
    private $_trademark         = NULL ;                    //  Trademark



    // --- OPERATIONS ---

    private function _returnValue($inString)
    {
        if (ord($inString) == 0) {
            if (function_exists('mb_convert_encoding')) {
                return mb_convert_encoding($inString,"UTF-8","UTF-16");
            } else {
                return str_replace(chr(00),'',$inString);
            }
        } else {
            return $inString;
        }
    }   //  function _returnValue()

    /**
     *  @access public
     *  @return integer
     */
    public function getCopyright()
    {
        return $this->_returnValue($this->_copyright);
    }   //  function getCopyright()


    /**
     *  @access public
     *  @return integer
     */
    public function getFontFamily()
    {
        return $this->_returnValue($this->_fontFamily);
    }   //  function getFontFamily()


    /**
     *  @access public
     *  @return integer
     */
    public function getFontSubFamily()
    {
        return $this->_returnValue($this->_fontSubFamily);
    }   //  function getFontSubFamily()


    /**
     *  @access public
     *  @return integer
     */
    public function getFontIdentifier()
    {
        return $this->_returnValue($this->_fontIdentifier);
    }   //  function getFontIdentifier()


    /**
     *  @access public
     *  @return integer
     */
    public function getFontName()
    {
        return $this->_returnValue($this->_fontName);
    }   //  function getFontName()


    /**
     *  @access public
     *  @return integer
     */
    public function getFontVersion()
    {
        return $this->_returnValue($this->_fontVersion);
    }   //  function getFontVersion()


    /**
     *  @access public
     *  @return integer
     */
    public function getPostscriptName()
    {
        return $this->_returnValue($this->_postscriptName);
    }   //  function getPostscriptName()


    /**
     *  @access public
     *  @return integer
     */
    public function getTrademark()
    {
        return $this->_returnValue($this->_trademark);
    }   //  function getTrademark()


    /**
     *  Convert a big-endian word or longword value to an integer
     *
     *  @access private
     *  @return integer
     */
    private function _UConvert($bytesValue,$byteCount)
    {
        $retVal = 0;
        $bytesLength = strlen($bytesValue);
        for ($i=0; $i < $bytesLength; $i++) {
            $tmpVal = ord($bytesValue{$i});
            $t = pow(256,($byteCount-$i-1));
            $retVal += $tmpVal*$t;
        }

        return $retVal;
    }   //  function UConvert()


    /**
     *  Convert a big-endian word value to an integer
     *
     *  @access private
     *  @return integer
     */
    private function _USHORT($stringValue) {
        return $this->_UConvert($stringValue,2);
    }


    /**
     *  Convert a big-endian word value to an integer
     *
     *  @access private
     *  @return integer
     */
    private function _ULONG($stringValue) {
        return $this->_UConvert($stringValue,4);
    }


    /**
     *  Read the Font Attributes
     *
     *  @access private
     *  @return integer
     */
    private function readFontAttributes() {
        $fontHandle = fopen($this->_fileName, "rb");

        //  Read the file header
        $TT_OFFSET_TABLE = fread($fontHandle, 12);

        $uMajorVersion  = $this->_USHORT(substr($TT_OFFSET_TABLE,0,2));
        $uMinorVersion  = $this->_USHORT(substr($TT_OFFSET_TABLE,2,2));
        $uNumOfTables   = $this->_USHORT(substr($TT_OFFSET_TABLE,4,2));
//      $uSearchRange   = $this->_USHORT(substr($TT_OFFSET_TABLE,6,2));
//      $uEntrySelector = $this->_USHORT(substr($TT_OFFSET_TABLE,8,2));
//      $uRangeShift    = $this->_USHORT(substr($TT_OFFSET_TABLE,10,2));

        //  Check is this is a true type font and the version is 1.0
        if ($uMajorVersion != 1 || $uMinorVersion != 0) {
            fclose($fontHandle);
            throw new Exception($this->_fileName.' is not a Truetype font file') ;
        }

        //  Look for details of the name table
        $nameTableFound = false;
        for ($t=0; $t < $uNumOfTables; $t++) {
            $TT_TABLE_DIRECTORY = fread($fontHandle, 16);
            $szTag = substr($TT_TABLE_DIRECTORY,0,4);
            if (strtolower($szTag) == 'name') {
//              $uCheckSum  = $this->_ULONG(substr($TT_TABLE_DIRECTORY,4,4));
                $uOffset    = $this->_ULONG(substr($TT_TABLE_DIRECTORY,8,4));
//              $uLength    = $this->_ULONG(substr($TT_TABLE_DIRECTORY,12,4));
                $nameTableFound = true;
                break;
            }
        }

        if (!$nameTableFound) {
            fclose($fontHandle);
            throw new Exception('Can\'t find name table in '.$this->_fileName) ;
        }

        //  Set offset to the start of the name table
        fseek($fontHandle,$uOffset,SEEK_SET);

        $TT_NAME_TABLE_HEADER = fread($fontHandle, 6);

//      $uFSelector     = $this->_USHORT(substr($TT_NAME_TABLE_HEADER,0,2));
        $uNRCount       = $this->_USHORT(substr($TT_NAME_TABLE_HEADER,2,2));
        $uStorageOffset = $this->_USHORT(substr($TT_NAME_TABLE_HEADER,4,2));

        $attributeCount = 0;
        for ($a=0; $a < $uNRCount; $a++) {
            $TT_NAME_RECORD = fread($fontHandle, 12);

            $uNameID = $this->_USHORT(substr($TT_NAME_RECORD,6,2));
            if ($uNameID <= 7) {
//              $uPlatformID    = $this->_USHORT(substr($TT_NAME_RECORD,0,2));
                $uEncodingID    = $this->_USHORT(substr($TT_NAME_RECORD,2,2));
//              $uLanguageID    = $this->_USHORT(substr($TT_NAME_RECORD,4,2));
                $uStringLength  = $this->_USHORT(substr($TT_NAME_RECORD,8,2));
                $uStringOffset  = $this->_USHORT(substr($TT_NAME_RECORD,10,2));

                if ($uStringLength > 0) {
                    $nPos = ftell($fontHandle);
                    fseek($fontHandle,$uOffset + $uStringOffset + $uStorageOffset,SEEK_SET);
                    $testValue = fread($fontHandle, $uStringLength);

                    if (trim($testValue) > '') {
                        switch ($uNameID) {
                            case 0  : if ($this->_copyright == NULL) {
                                        $this->_copyright = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 1  : if ($this->_fontFamily == NULL) {
                                        $this->_fontFamily = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 2  : if ($this->_fontSubFamily == NULL) {
                                        $this->_fontSubFamily = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 3  : if ($this->_fontIdentifier == NULL) {
                                        $this->_fontIdentifier = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 4  : if ($this->_fontName == NULL) {
                                        $this->_fontName = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 5  : if ($this->_fontVersion == NULL) {
                                        $this->_fontVersion = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 6  : if ($this->_postscriptName == NULL) {
                                        $this->_postscriptName = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 7  : if ($this->_trademark == NULL) {
                                        $this->_trademark = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                        }
                    }
                    fseek($fontHandle,$nPos,SEEK_SET);
                }
            }
            if ($attributeCount > 7) {
                break;
            }
        }

        fclose($fontHandle);
        return true;
    }




    /**
     *  @access constructor
     *  @return void
     */
    function __construct($fileName='') {

        if ($fileName == '') {
            throw new Exception('Font File has not been specified') ;
        }

        $this->_fileName = $fileName;

        if (!file_exists($this->_fileName)) {
            throw new Exception($this->_fileName.' does not exist') ;
        } elseif (!is_readable($this->_fileName)) {
            throw new Exception($this->_fileName.' is not a readable file') ;
        }

        return $this->readFontAttributes();
    }   //  function constructor()


}   /* end of class fontAttributes */

Very similar to the previously posted answer... I've been using this class for a long time now.

class fontAttributes extends baseClass
{
    // --- ATTRIBUTES ---

    /**
     *  @access private
     *  @var string
     */
    private $_fileName          = NULL ;                    //  Name of the truetype font file


    /**
     *  @access private
     *  @var string
     */
    private $_copyright         = NULL ;                    //  Copyright


    /**
     *  @access private
     *  @var string
     */
    private $_fontFamily        = NULL ;                    //  Font Family


    /**
     *  @access private
     *  @var string
     */
    private $_fontSubFamily     = NULL ;                    //  Font SubFamily


    /**
     *  @access private
     *  @var string
     */
    private $_fontIdentifier    = NULL ;                    //  Font Unique Identifier


    /**
     *  @access private
     *  @var string
     */
    private $_fontName          = NULL ;                    //  Font Name


    /**
     *  @access private
     *  @var string
     */
    private $_fontVersion       = NULL ;                    //  Font Version


    /**
     *  @access private
     *  @var string
     */
    private $_postscriptName    = NULL ;                    //  Postscript Name


    /**
     *  @access private
     *  @var string
     */
    private $_trademark         = NULL ;                    //  Trademark



    // --- OPERATIONS ---

    private function _returnValue($inString)
    {
        if (ord($inString) == 0) {
            if (function_exists('mb_convert_encoding')) {
                return mb_convert_encoding($inString,"UTF-8","UTF-16");
            } else {
                return str_replace(chr(00),'',$inString);
            }
        } else {
            return $inString;
        }
    }   //  function _returnValue()

    /**
     *  @access public
     *  @return integer
     */
    public function getCopyright()
    {
        return $this->_returnValue($this->_copyright);
    }   //  function getCopyright()


    /**
     *  @access public
     *  @return integer
     */
    public function getFontFamily()
    {
        return $this->_returnValue($this->_fontFamily);
    }   //  function getFontFamily()


    /**
     *  @access public
     *  @return integer
     */
    public function getFontSubFamily()
    {
        return $this->_returnValue($this->_fontSubFamily);
    }   //  function getFontSubFamily()


    /**
     *  @access public
     *  @return integer
     */
    public function getFontIdentifier()
    {
        return $this->_returnValue($this->_fontIdentifier);
    }   //  function getFontIdentifier()


    /**
     *  @access public
     *  @return integer
     */
    public function getFontName()
    {
        return $this->_returnValue($this->_fontName);
    }   //  function getFontName()


    /**
     *  @access public
     *  @return integer
     */
    public function getFontVersion()
    {
        return $this->_returnValue($this->_fontVersion);
    }   //  function getFontVersion()


    /**
     *  @access public
     *  @return integer
     */
    public function getPostscriptName()
    {
        return $this->_returnValue($this->_postscriptName);
    }   //  function getPostscriptName()


    /**
     *  @access public
     *  @return integer
     */
    public function getTrademark()
    {
        return $this->_returnValue($this->_trademark);
    }   //  function getTrademark()


    /**
     *  Convert a big-endian word or longword value to an integer
     *
     *  @access private
     *  @return integer
     */
    private function _UConvert($bytesValue,$byteCount)
    {
        $retVal = 0;
        $bytesLength = strlen($bytesValue);
        for ($i=0; $i < $bytesLength; $i++) {
            $tmpVal = ord($bytesValue{$i});
            $t = pow(256,($byteCount-$i-1));
            $retVal += $tmpVal*$t;
        }

        return $retVal;
    }   //  function UConvert()


    /**
     *  Convert a big-endian word value to an integer
     *
     *  @access private
     *  @return integer
     */
    private function _USHORT($stringValue) {
        return $this->_UConvert($stringValue,2);
    }


    /**
     *  Convert a big-endian word value to an integer
     *
     *  @access private
     *  @return integer
     */
    private function _ULONG($stringValue) {
        return $this->_UConvert($stringValue,4);
    }


    /**
     *  Read the Font Attributes
     *
     *  @access private
     *  @return integer
     */
    private function readFontAttributes() {
        $fontHandle = fopen($this->_fileName, "rb");

        //  Read the file header
        $TT_OFFSET_TABLE = fread($fontHandle, 12);

        $uMajorVersion  = $this->_USHORT(substr($TT_OFFSET_TABLE,0,2));
        $uMinorVersion  = $this->_USHORT(substr($TT_OFFSET_TABLE,2,2));
        $uNumOfTables   = $this->_USHORT(substr($TT_OFFSET_TABLE,4,2));
//      $uSearchRange   = $this->_USHORT(substr($TT_OFFSET_TABLE,6,2));
//      $uEntrySelector = $this->_USHORT(substr($TT_OFFSET_TABLE,8,2));
//      $uRangeShift    = $this->_USHORT(substr($TT_OFFSET_TABLE,10,2));

        //  Check is this is a true type font and the version is 1.0
        if ($uMajorVersion != 1 || $uMinorVersion != 0) {
            fclose($fontHandle);
            throw new Exception($this->_fileName.' is not a Truetype font file') ;
        }

        //  Look for details of the name table
        $nameTableFound = false;
        for ($t=0; $t < $uNumOfTables; $t++) {
            $TT_TABLE_DIRECTORY = fread($fontHandle, 16);
            $szTag = substr($TT_TABLE_DIRECTORY,0,4);
            if (strtolower($szTag) == 'name') {
//              $uCheckSum  = $this->_ULONG(substr($TT_TABLE_DIRECTORY,4,4));
                $uOffset    = $this->_ULONG(substr($TT_TABLE_DIRECTORY,8,4));
//              $uLength    = $this->_ULONG(substr($TT_TABLE_DIRECTORY,12,4));
                $nameTableFound = true;
                break;
            }
        }

        if (!$nameTableFound) {
            fclose($fontHandle);
            throw new Exception('Can\'t find name table in '.$this->_fileName) ;
        }

        //  Set offset to the start of the name table
        fseek($fontHandle,$uOffset,SEEK_SET);

        $TT_NAME_TABLE_HEADER = fread($fontHandle, 6);

//      $uFSelector     = $this->_USHORT(substr($TT_NAME_TABLE_HEADER,0,2));
        $uNRCount       = $this->_USHORT(substr($TT_NAME_TABLE_HEADER,2,2));
        $uStorageOffset = $this->_USHORT(substr($TT_NAME_TABLE_HEADER,4,2));

        $attributeCount = 0;
        for ($a=0; $a < $uNRCount; $a++) {
            $TT_NAME_RECORD = fread($fontHandle, 12);

            $uNameID = $this->_USHORT(substr($TT_NAME_RECORD,6,2));
            if ($uNameID <= 7) {
//              $uPlatformID    = $this->_USHORT(substr($TT_NAME_RECORD,0,2));
                $uEncodingID    = $this->_USHORT(substr($TT_NAME_RECORD,2,2));
//              $uLanguageID    = $this->_USHORT(substr($TT_NAME_RECORD,4,2));
                $uStringLength  = $this->_USHORT(substr($TT_NAME_RECORD,8,2));
                $uStringOffset  = $this->_USHORT(substr($TT_NAME_RECORD,10,2));

                if ($uStringLength > 0) {
                    $nPos = ftell($fontHandle);
                    fseek($fontHandle,$uOffset + $uStringOffset + $uStorageOffset,SEEK_SET);
                    $testValue = fread($fontHandle, $uStringLength);

                    if (trim($testValue) > '') {
                        switch ($uNameID) {
                            case 0  : if ($this->_copyright == NULL) {
                                        $this->_copyright = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 1  : if ($this->_fontFamily == NULL) {
                                        $this->_fontFamily = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 2  : if ($this->_fontSubFamily == NULL) {
                                        $this->_fontSubFamily = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 3  : if ($this->_fontIdentifier == NULL) {
                                        $this->_fontIdentifier = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 4  : if ($this->_fontName == NULL) {
                                        $this->_fontName = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 5  : if ($this->_fontVersion == NULL) {
                                        $this->_fontVersion = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 6  : if ($this->_postscriptName == NULL) {
                                        $this->_postscriptName = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                            case 7  : if ($this->_trademark == NULL) {
                                        $this->_trademark = $testValue;
                                        $attributeCount++;
                                      }
                                      break;
                        }
                    }
                    fseek($fontHandle,$nPos,SEEK_SET);
                }
            }
            if ($attributeCount > 7) {
                break;
            }
        }

        fclose($fontHandle);
        return true;
    }




    /**
     *  @access constructor
     *  @return void
     */
    function __construct($fileName='') {

        if ($fileName == '') {
            throw new Exception('Font File has not been specified') ;
        }

        $this->_fileName = $fileName;

        if (!file_exists($this->_fileName)) {
            throw new Exception($this->_fileName.' does not exist') ;
        } elseif (!is_readable($this->_fileName)) {
            throw new Exception($this->_fileName.' is not a readable file') ;
        }

        return $this->readFontAttributes();
    }   //  function constructor()


}   /* end of class fontAttributes */
梦太阳 2024-11-08 05:13:17

既然 DOMPDF 项目的优秀人员已经为您完成了工作,为什么还要重新发明轮子呢?看看 php-font-lib @ https://github.com/PhenX/php-font -lib。它具有您所要求的所有功能,并且还支持其他字体格式。查看演示 UI @ http://pxd.me/php-font-lib /www/font_explorer.html 了解您可以从此库中获取哪些类型的信息。

Why reinvent the wheel when the fine people at DOMPDF project has already done the work for you? Take a look at php-font-lib @ https://github.com/PhenX/php-font-lib. This has all the features that you have asked for and supports other font formats as well. Look at the demo UI @ http://pxd.me/php-font-lib/www/font_explorer.html to get an idea about what kind of information you can get from this library.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文