⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opentype.php

📁 Bug tracker, and reporter.
💻 PHP
📖 第 1 页 / 共 3 页
字号:
<?php/** * Zend Framework * * LICENSE * * This source file is subject to the new BSD license that is bundled * with this package in the file LICENSE.txt. * It is also available through the world-wide-web at this URL: * http://framework.zend.com/license/new-bsd * If you did not receive a copy of the license and are unable to * obtain it through the world-wide-web, please send an email * to license@zend.com so we can send you a copy immediately. * * @package    Zend_Pdf * @subpackage FileParser * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) * @license    http://framework.zend.com/license/new-bsd     New BSD License *//** Zend_Pdf_FileParser_Font */require_once 'Zend/Pdf/FileParser/Font.php';/** Zend_Pdf_Cmap */require_once 'Zend/Pdf/Cmap.php';/** * Abstract base class for OpenType font file parsers. * * TrueType was originally developed by Apple and was adopted as the default * font format for the Microsoft Windows platform. OpenType is an extension of * TrueType, developed jointly by Microsoft and Adobe, which adds support for * PostScript font data. * * This abstract parser class forms the foundation for concrete subclasses which * extract either TrueType or PostScript font data from the file. * * All OpenType files use big-endian byte ordering. * * The full TrueType and OpenType specifications can be found at: * <ul> *  <li>{@link http://developer.apple.com/textfonts/TTRefMan/} *  <li>{@link http://www.microsoft.com/typography/OTSPEC/} *  <li>{@link http://partners.adobe.com/public/developer/opentype/index_spec.html} * </ul> * * @package    Zend_Pdf * @subpackage FileParser * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) * @license    http://framework.zend.com/license/new-bsd     New BSD License */abstract class Zend_Pdf_FileParser_Font_OpenType extends Zend_Pdf_FileParser_Font{  /**** Instance Variables ****/    /**     * Stores the scaler type (font type) for the font file. See     * {@link _readScalerType()}.     * @var integer     */    protected $_scalerType = 0;    /**     * Stores the byte offsets to the various information tables.     * @var array     */    protected $_tableDirectory = array();  /**** Public Interface ****/  /* Semi-Concrete Class Implementation */    /**     * Verifies that the font file is in the expected format.     *     * NOTE: This method should be overridden in subclasses to check the     * specific format and set $this->_isScreened!     *     * @throws Zend_Pdf_Exception     */    public function screen()    {        if ($this->_isScreened) {            return;        }        $this->_readScalerType();    }    /**     * Reads and parses the font data from the file on disk.     *     * NOTE: This method should be overridden in subclasses to add type-     * specific parsing and set $this->isParsed.     *     * @throws Zend_Pdf_Exception     */    public function parse()    {        if ($this->_isParsed) {            return;        }        /* Screen the font file first, if it hasn't been done yet.        */        $this->screen();        /* Start by reading the table directory.         */        $this->_parseTableDirectory();        /* Then parse all of the required tables.         */        $this->_parseHeadTable();        $this->_parseNameTable();        $this->_parsePostTable();        $this->_parseHheaTable();        $this->_parseMaxpTable();
        $this->_parseOs2Table();        $this->_parseHmtxTable();        $this->_parseCmapTable();        /* If present, parse the optional tables.         */        /**         * @todo Add parser for kerning pairs.         * @todo Add parser for ligatures.         * @todo Add parser for other useful hinting tables.         */    }  /**** Internal Methods ****/  /* Parser Methods */    /**     * Parses the OpenType table directory.     *     * The table directory contains the identifier, checksum, byte offset, and     * length of each of the information tables housed in the font file.     *     * @throws Zend_Pdf_Exception     */    protected function _parseTableDirectory()    {        $this->moveToOffset(4);        $tableCount = $this->readUInt(2);        $this->_debugLog('%d tables', $tableCount);        /* Sanity check, in case we're not actually reading a OpenType file and         * the first four bytes coincidentally matched an OpenType signature in         * screen() above.         *         * There are at minimum 7 required tables: cmap, head, hhea, hmtx, maxp,         * name, and post. In the current OpenType standard, only 32 table types         * are defined, so use 50 as a practical limit.         */        if (($tableCount < 7) || ($tableCount > 50)) {            throw new Zend_Pdf_Exception('Table count not within expected range',                                         Zend_Pdf_Exception::BAD_TABLE_COUNT);        }        /* Skip the next 6 bytes, which contain values to aid a binary search.         */        $this->skipBytes(6);        /* The directory contains four values: the name of the table, checksum,         * offset to the table from the beginning of the font, and actual data         * length of the table.         */        for ($tableIndex = 0; $tableIndex < $tableCount; $tableIndex++) {            $tableName = $this->readBytes(4);            /* We ignore the checksum here for two reasons: First, the PDF viewer             * will do this later anyway; Second, calculating the checksum would             * require unsigned integers, which PHP does not currently provide.             * We may revisit this in the future.             */            $this->skipBytes(4);            $tableOffset = $this->readUInt(4);            $tableLength = $this->readUInt(4);            $this->_debugLog('%s offset: 0x%x; length: %d', $tableName, $tableOffset, $tableLength);            /* Sanity checks for offset and length values.             */            $fileSize = $this->_dataSource->getSize();            if (($tableOffset < 0) || ($tableOffset > $fileSize)) {                throw new Zend_Pdf_Exception("Table offset ($tableOffset) not within expected range",                                             Zend_Pdf_Exception::INDEX_OUT_OF_RANGE);            }            if (($tableLength < 0) || (($tableOffset + $tableLength) > $fileSize)) {                throw new Zend_Pdf_Exception("Table length ($tableLength) not within expected range",                                             Zend_Pdf_Exception::INDEX_OUT_OF_RANGE);            }            $this->_tableDirectory[$tableName]['offset'] = $tableOffset;            $this->_tableDirectory[$tableName]['length'] = $tableLength;        }    }    /**     * Parses the OpenType head (Font Header) table.     *     * The head table contains global information about the font such as the     * revision number and global metrics.     *     * @throws Zend_Pdf_Exception     */    protected function _parseHeadTable()    {        $this->_jumpToTable('head');        /* We can read any version 1 table.         */        $tableVersion = $this->_readTableVersion(1, 1);        /* Skip the font revision number and checksum adjustment.         */        $this->skipBytes(8);        $magicNumber = $this->readUInt(4);        if ($magicNumber != 0x5f0f3cf5) {            throw new Zend_Pdf_Exception('Wrong magic number. Expected: 0x5f0f3cf5; actual: '                                       . sprintf('%x', $magicNumber),                                         Zend_Pdf_Exception::BAD_MAGIC_NUMBER);        }        /* Most of the flags we ignore, but there are a few values that are         * useful for our layout routines.         */        $flags = $this->readUInt(2);        $this->baselineAtZero    = $this->isBitSet(0, $flags);        $this->useIntegerScaling = $this->isBitSet(3, $flags);        $this->unitsPerEm = $this->readUInt(2);        $this->_debugLog('Units per em: %d', $this->unitsPerEm);        /* Skip creation and modification date/time.         */        $this->skipBytes(16);        $this->xMin = $this->readInt(2);        $this->yMin = $this->readInt(2);        $this->xMax = $this->readInt(2);        $this->yMax = $this->readInt(2);        $this->_debugLog('Font bounding box: %d %d %d %d',                         $this->xMin, $this->yMin, $this->xMax, $this->yMax);        /* The style bits here must match the fsSelection bits in the OS/2         * table, if present.         */        $macStyleBits = $this->readUInt(2);        $this->isBold   = $this->isBitSet(0, $macStyleBits);        $this->isItalic = $this->isBitSet(1, $macStyleBits);        /* We don't need the remainder of data in this table: smallest readable         * size, font direction hint, indexToLocFormat, and glyphDataFormat.         */    }    /**     * Parses the OpenType name (Naming) table.     *     * The name table contains all of the identifying strings associated with     * the font such as its name, copyright, trademark, license, etc.     *     * @throws Zend_Pdf_Exception     */    protected function _parseNameTable()    {        $this->_jumpToTable('name');        $baseOffset = $this->_tableDirectory['name']['offset'];        /* The name table begins with a short header, followed by each of the         * fixed-length name records, followed by the variable-length strings.         */        /* We only understand version 0 tables.         */        $tableFormat = $this->readUInt(2);        if ($tableFormat != 0) {            throw new Zend_Pdf_Exception("Unable to read format $tableFormat table",                                         Zend_Pdf_Exception::DONT_UNDERSTAND_TABLE_VERSION);        }        $this->_debugLog('Format %d table', $tableFormat);        $nameCount = $this->readUInt(2);        $this->_debugLog('%d name strings', $nameCount);        $storageOffset = $this->readUInt(2) + $baseOffset;        $this->_debugLog('Storage offset: 0x%x', $storageOffset);        /* Scan the name records for those we're interested in. We'll skip over         * encodings and languages we don't understand or support. Prefer the         * Microsoft Unicode encoding for a given name/language combination, but         * use Mac Roman if nothing else is available. We will extract the         * actual strings later.         */        $nameRecords = array();        for ($nameIndex = 0; $nameIndex < $nameCount; $nameIndex++) {            $platformID = $this->readUInt(2);            $encodingID = $this->readUInt(2);            if (! ( (($platformID == 3) && ($encodingID == 1)) ||    // Microsoft Unicode                    (($platformID == 1) && ($encodingID == 0))       // Mac Roman                   ) ) {                $this->skipBytes(8);    // Not a supported encoding. Move on.                continue;            }            $languageID = $this->readUInt(2);            $nameID     = $this->readUInt(2);            $nameLength = $this->readUInt(2);            $nameOffset = $this->readUInt(2);            $languageCode = $this->_languageCodeForPlatform($platformID, $languageID);            if (is_null($languageCode)) {                $this->_debugLog('Skipping languageID: 0x%x; platformID %d', $languageID, $platformID);                continue;    // Not a supported language. Move on.            }            $this->_debugLog('Adding nameID: %d; languageID: 0x%x; platformID: %d; offset: 0x%x (0x%x); length: %d',                             $nameID, $languageID, $platformID, $baseOffset + $nameOffset, $nameOffset, $nameLength);            /* Entries in the name table are sorted by platform ID. If an entry             * exists for both Mac Roman and Microsoft Unicode, the Unicode entry             * will prevail since it is processed last.             */            $nameRecords[$nameID][$languageCode] = array('platform' => $platformID,                                                         'offset'   => $nameOffset,                                                         'length'   => $nameLength );        }        /* Now go back and extract the interesting strings.         */        $fontNames = array();        foreach ($nameRecords as $name => $languages) {            foreach ($languages as $language => $attributes) {                $stringOffset = $storageOffset + $attributes['offset'];                $this->moveToOffset($stringOffset);                if ($attributes['platform'] == 3) {                    $string = $this->readStringUTF16($attributes['length']);                } else {                    $string = $this->readStringMacRoman($attributes['length']);                }                $fontNames[$name][$language] = $string;            }        }        $this->names = $fontNames;    }    /**     * Parses the OpenType post (PostScript Information) table.     *     * The post table contains additional information required for using the font     * on PostScript printers. It also contains the preferred location and

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -