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

📄 opentype.php

📁 Bug tracker, and reporter.
💻 PHP
📖 第 1 页 / 共 3 页
字号:
         * the glyph's advance width and its left side bearing. We don't use the         * left side bearing.         */        $glyphWidths = array();        for ($i = 0; $i < $this->numberHMetrics; $i++) {            $glyphWidths[$i] = $this->readUInt(2);            $this->skipBytes(2);        }
        /* Populate last value for the rest of array
         */        while (count($glyphWidths) < $this->numGlyphs) {
            $glyphWidths[] = end($glyphWidths);
        }
        $this->glyphWidths = $glyphWidths;        /* There is an optional table of left side bearings which is sometimes         * used for monospaced fonts. We don't use the left side bearing, so         * we can safely ignore it.         */    }    /**     * Parses the OpenType cmap (Character to Glyph Mapping) table.     *     * The cmap table provides the maps from character codes to font glyphs.     * There are usually at least two character maps in a font: Microsoft Unicode     * and Macintosh Roman. For very complex fonts, there may also be mappings     * for the characters in the Unicode Surrogates Area, which are UCS-4     * characters.     *     * @todo Need to rework the selection logic for picking a subtable. We should     *   have an explicit list of preferences, followed by a list of those that     *   are tolerable. Most specifically, since everything above this layer deals     *   in Unicode, we need to be sure to only accept format 0 MacRoman tables.     *     * @throws Zend_Pdf_Exception     */    protected function _parseCmapTable()    {        $this->_jumpToTable('cmap');        $baseOffset = $this->_tableDirectory['cmap']['offset'];        /* We only understand version 0 tables.         */        $tableVersion = $this->readUInt(2);        if ($tableVersion != 0) {            throw new Zend_Pdf_Exception("Unable to read version $tableVersion table",                                         Zend_Pdf_Exception::DONT_UNDERSTAND_TABLE_VERSION);        }        $this->_debugLog('Version %d table', $tableVersion);        $subtableCount = $this->readUInt(2);        $this->_debugLog('%d subtables', $subtableCount);        /* Like the name table, there may be many different encoding subtables         * present. Ideally, we are looking for an acceptable Unicode table.         */        $subtables = array();        for ($subtableIndex = 0; $subtableIndex < $subtableCount; $subtableIndex++) {            $platformID = $this->readUInt(2);            $encodingID = $this->readUInt(2);            if (! ( (($platformID == 0) && ($encodingID == 3)) ||    // Unicode 2.0 or later                    (($platformID == 0) && ($encodingID == 0)) ||    // Unicode                    (($platformID == 3) && ($encodingID == 1)) ||    // Microsoft Unicode                    (($platformID == 1) && ($encodingID == 0))       // Mac Roman                   ) ) {                $this->_debugLog('Unsupported encoding: platformID: %d; encodingID: %d; skipping',                                 $platformID, $encodingID);                $this->skipBytes(4);                continue;            }            $subtableOffset = $this->readUInt(4);            if ($subtableOffset < 0) {    // Sanity check for 4-byte unsigned on 32-bit platform                $this->_debugLog('Offset 0x%x out of range for platformID: %d; skipping',                                 $subtableOffset, $platformID);                continue;            }            $this->_debugLog('Found subtable; platformID: %d; encodingID: %d; offset: 0x%x (0x%x)',                             $platformID, $encodingID, $baseOffset + $subtableOffset, $subtableOffset);            $subtables[$platformID][$encodingID][] = $subtableOffset;        }        /* In preferred order, find a subtable to use.         */        $offsets = array();        /* Unicode 2.0 or later semantics         */        if (isset($subtables[0][3])) {            foreach ($subtables[0][3] as $offset) {                $offsets[] = $offset;            }        }        /* Unicode default semantics         */        if (isset($subtables[0][0])) {            foreach ($subtables[0][0] as $offset) {                $offsets[] = $offset;            }        }        /* Microsoft Unicode         */        if (isset($subtables[3][1])) {            foreach ($subtables[3][1] as $offset) {                $offsets[] = $offset;            }        }        /* Mac Roman.         */        if (isset($subtables[1][0])) {            foreach ($subtables[1][0] as $offset) {                $offsets[] = $offset;            }        }        $cmapType = -1;        foreach ($offsets as $offset) {            $cmapOffset = $baseOffset + $offset;            $this->moveToOffset($cmapOffset);            $format = $this->readUInt(2);            $language = -1;            switch ($format) {                case 0x0:                    $cmapLength = $this->readUInt(2);                    $language = $this->readUInt(2);                    if ($language != 0) {                        $this->_debugLog('Type 0 cmap tables must be language-independent;'                                         . ' language: %d; skipping', $language);                        continue;                    }                    break;                case 0x4:    // break intentionally omitted                case 0x6:                    $cmapLength = $this->readUInt(2);                    $language = $this->readUInt(2);                    if ($language != 0) {                        $this->_debugLog('Warning: cmap tables must be language-independent - this font'                                         . ' may not work properly; language: %d', $language);                    }                    break;                case 0x2:    // break intentionally omitted                case 0x8:    // break intentionally omitted                case 0xa:    // break intentionally omitted                case 0xc:                    $this->_debugLog('Format: 0x%x currently unsupported; skipping', $format);                    continue;                    //$this->skipBytes(2);                    //$cmapLength = $this->readUInt(4);                    //$language = $this->readUInt(4);                    //if ($language != 0) {                    //    $this->_debugLog('Warning: cmap tables must be language-independent - this font'                    //                     . ' may not work properly; language: %d', $language);                    //}                    //break;                default:                    $this->_debugLog('Unknown subtable format: 0x%x; skipping', $format);                    continue;            }            $cmapType = $format;            break;        }        if ($cmapType == -1) {            throw new Zend_Pdf_Exception('Unable to find usable cmap table',                                         Zend_Pdf_Exception::CANT_FIND_GOOD_CMAP);        }        /* Now extract the subtable data and create a Zend_Pdf_FontCmap object.         */        $this->_debugLog('Using cmap type %d; offset: 0x%x; length: %d',                         $cmapType, $cmapOffset, $cmapLength);        $this->moveToOffset($cmapOffset);        $cmapData = $this->readBytes($cmapLength);        $this->cmap = Zend_Pdf_Cmap::cmapWithTypeData($cmapType, $cmapData);    }    /**     * Reads the scaler type from the header of the OpenType font file and     * returns it as an unsigned long integer.     *     * The scaler type defines the type of font: OpenType font files may contain     * TrueType or PostScript outlines. Throws an exception if the scaler type     * is not recognized.     *     * @return integer     * @throws Zend_Pdf_Exception     */    protected function _readScalerType()    {        if ($this->_scalerType != 0) {            return $this->_scalerType;        }        $this->moveToOffset(0);        $this->_scalerType = $this->readUInt(4);        switch ($this->_scalerType) {            case 0x00010000:    // version 1.0 - Windows TrueType signature                $this->_debugLog('Windows TrueType signature');                break;            case 0x74727565:    // 'true' - Macintosh TrueType signature                $this->_debugLog('Macintosh TrueType signature');                break;            case 0x4f54544f:    // 'OTTO' - the CFF signature                $this->_debugLog('PostScript CFF signature');                break;            case 0x74797031:    // 'typ1'                throw new Zend_Pdf_Exception('Unsupported font type: PostScript in sfnt wrapper',                                             Zend_Pdf_Exception::WRONG_FONT_TYPE);            default:                throw new Zend_Pdf_Exception('Not an OpenType font file',                                             Zend_Pdf_Exception::WRONG_FONT_TYPE);        }        return $this->_scalerType;    }    /**     * Validates a given table's existence, then sets the file pointer to the     * start of that table.     *     * @param string $tableName     * @throws Zend_Pdf_Exception     */    protected function _jumpToTable($tableName)    {        if (empty($this->_tableDirectory[$tableName])) {    // do not allow NULL or zero            throw new Zend_Pdf_Exception("Required table '$tableName' not found!",                                         Zend_Pdf_Exception::REQUIRED_TABLE_NOT_FOUND);        }        $this->_debugLog("Parsing $tableName table...");        $this->moveToOffset($this->_tableDirectory[$tableName]['offset']);    }    /**     * Reads the fixed 16.16 table version number and checks for compatibility.     * If the version is incompatible, throws an exception. If it is compatible,     * returns the version number.     *     * @param float $minVersion Minimum compatible version number.     * @param float $maxVertion Maximum compatible version number.     * @return float Table version number.     * @throws Zend_Pdf_Exception     */    protected function _readTableVersion($minVersion, $maxVersion)    {        $tableVersion = $this->readFixed(16, 16);        if (($tableVersion < $minVersion) || ($tableVersion > $maxVersion)) {            throw new Zend_Pdf_Exception("Unable to read version $tableVersion table",                                         Zend_Pdf_Exception::DONT_UNDERSTAND_TABLE_VERSION);        }        $this->_debugLog('Version %.2f table', $tableVersion);        return $tableVersion;    }    /**     * Utility method that returns ISO 639 two-letter language codes from the     * TrueType platform and language ID. Returns NULL for languages that are     * not supported.     *     * @param integer $platformID     * @param integer $encodingID     * @return string | null     */    protected function _languageCodeForPlatform($platformID, $languageID)    {        if ($platformID == 3) {    // Microsoft encoding.            /* The low-order bytes specify the language, the high-order bytes             * specify the dialect. We just care about the language. For the             * complete list, see:             *   http://www.microsoft.com/globaldev/reference/lcid-all.mspx             */            $languageID &= 0xff;            switch ($languageID) {                case 0x09:                    return 'en';                case 0x0c:                    return 'fr';                case 0x07:                    return 'de';                case 0x10:                    return 'it';                case 0x13:                    return 'nl';                case 0x1d:                    return 'sv';                case 0x0a:                    return 'es';                case 0x06:                    return 'da';                case 0x16:                    return 'pt';                case 0x14:                    return 'no';                case 0x0d:                    return 'he';                case 0x11:                    return 'ja';                case 0x01:                    return 'ar';                case 0x0b:                    return 'fi';                case 0x08:                    return 'el';                default:                    return null;            }        } else if ($platformID == 1) {    // Macintosh encoding.            switch ($languageID) {                case 0:                    return 'en';                case 1:                    return 'fr';                case 2:                    return 'de';                case 3:                    return 'it';                case 4:                    return 'nl';                case 5:                    return 'sv';                case 6:                    return 'es';                case 7:                    return 'da';                case 8:                    return 'pt';                case 9:                    return 'no';                case 10:                    return 'he';                case 11:                    return 'ja';                case 12:                    return 'ar';                case 13:                    return 'fi';                case 14:                    return 'el';                default:                    return null;            }        } else {    // Unknown encoding.            return null;        }    }}

⌨️ 快捷键说明

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