首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何从.ttf文件中读取字体的标题?

如何从.ttf文件中读取字体的标题?
EN

Stack Overflow用户
提问于 2011-04-15 03:55:00
回答 2查看 15.9K关注 0票数 22

我真的需要能够从.ttf真类型字体文件中提取元数据。

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

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

我只是真的需要阅读这个元数据部分的帮助。

EN

回答 2

Stack Overflow用户

发布于 2011-04-15 04:28:14

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

代码语言:javascript
复制
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 */
票数 4
EN

Stack Overflow用户

发布于 2014-12-30 23:53:39

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5668901

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档