X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=vendor%2Fphenx%2Fphp-font-lib%2Fsrc%2FFontLib%2FTrueType%2FFile.php;fp=vendor%2Fphenx%2Fphp-font-lib%2Fsrc%2FFontLib%2FTrueType%2FFile.php;h=b8a580afd21482cf23f420ebf15aa24ad63f6eb0;hp=0000000000000000000000000000000000000000;hb=0bf8d09d2542548982e81a441b1f16e75873a04f;hpb=74df008bdbb3a11eeea356744f39b802369bda3c diff --git a/vendor/phenx/php-font-lib/src/FontLib/TrueType/File.php b/vendor/phenx/php-font-lib/src/FontLib/TrueType/File.php new file mode 100644 index 000000000..b8a580afd --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/TrueType/File.php @@ -0,0 +1,471 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\TrueType; + +use FontLib\AdobeFontMetrics; +use FontLib\Font; +use FontLib\BinaryStream; +use FontLib\Table\Table; +use FontLib\Table\DirectoryEntry; +use FontLib\Table\Type\glyf; +use FontLib\Table\Type\name; +use FontLib\Table\Type\nameRecord; + +/** + * TrueType font file. + * + * @package php-font-lib + */ +class File extends BinaryStream { + /** + * @var Header + */ + public $header = array(); + + private $tableOffset = 0; // Used for TTC + + private static $raw = false; + + protected $directory = array(); + protected $data = array(); + + protected $glyph_subset = array(); + + public $glyph_all = array(); + + static $macCharNames = array( + ".notdef", ".null", "CR", + "space", "exclam", "quotedbl", "numbersign", + "dollar", "percent", "ampersand", "quotesingle", + "parenleft", "parenright", "asterisk", "plus", + "comma", "hyphen", "period", "slash", + "zero", "one", "two", "three", + "four", "five", "six", "seven", + "eight", "nine", "colon", "semicolon", + "less", "equal", "greater", "question", + "at", "A", "B", "C", "D", "E", "F", "G", + "H", "I", "J", "K", "L", "M", "N", "O", + "P", "Q", "R", "S", "T", "U", "V", "W", + "X", "Y", "Z", "bracketleft", + "backslash", "bracketright", "asciicircum", "underscore", + "grave", "a", "b", "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", "m", "n", "o", + "p", "q", "r", "s", "t", "u", "v", "w", + "x", "y", "z", "braceleft", + "bar", "braceright", "asciitilde", "Adieresis", + "Aring", "Ccedilla", "Eacute", "Ntilde", + "Odieresis", "Udieresis", "aacute", "agrave", + "acircumflex", "adieresis", "atilde", "aring", + "ccedilla", "eacute", "egrave", "ecircumflex", + "edieresis", "iacute", "igrave", "icircumflex", + "idieresis", "ntilde", "oacute", "ograve", + "ocircumflex", "odieresis", "otilde", "uacute", + "ugrave", "ucircumflex", "udieresis", "dagger", + "degree", "cent", "sterling", "section", + "bullet", "paragraph", "germandbls", "registered", + "copyright", "trademark", "acute", "dieresis", + "notequal", "AE", "Oslash", "infinity", + "plusminus", "lessequal", "greaterequal", "yen", + "mu", "partialdiff", "summation", "product", + "pi", "integral", "ordfeminine", "ordmasculine", + "Omega", "ae", "oslash", "questiondown", + "exclamdown", "logicalnot", "radical", "florin", + "approxequal", "increment", "guillemotleft", "guillemotright", + "ellipsis", "nbspace", "Agrave", "Atilde", + "Otilde", "OE", "oe", "endash", + "emdash", "quotedblleft", "quotedblright", "quoteleft", + "quoteright", "divide", "lozenge", "ydieresis", + "Ydieresis", "fraction", "currency", "guilsinglleft", + "guilsinglright", "fi", "fl", "daggerdbl", + "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", + "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", + "Egrave", "Iacute", "Icircumflex", "Idieresis", + "Igrave", "Oacute", "Ocircumflex", "applelogo", + "Ograve", "Uacute", "Ucircumflex", "Ugrave", + "dotlessi", "circumflex", "tilde", "macron", + "breve", "dotaccent", "ring", "cedilla", + "hungarumlaut", "ogonek", "caron", "Lslash", + "lslash", "Scaron", "scaron", "Zcaron", + "zcaron", "brokenbar", "Eth", "eth", + "Yacute", "yacute", "Thorn", "thorn", + "minus", "multiply", "onesuperior", "twosuperior", + "threesuperior", "onehalf", "onequarter", "threequarters", + "franc", "Gbreve", "gbreve", "Idot", + "Scedilla", "scedilla", "Cacute", "cacute", + "Ccaron", "ccaron", "dmacron" + ); + + function getTable() { + $this->parseTableEntries(); + + return $this->directory; + } + + function setTableOffset($offset) { + $this->tableOffset = $offset; + } + + function parse() { + $this->parseTableEntries(); + + $this->data = array(); + + foreach ($this->directory as $tag => $table) { + if (empty($this->data[$tag])) { + $this->readTable($tag); + } + } + } + + function utf8toUnicode($str) { + $len = strlen($str); + $out = array(); + + for ($i = 0; $i < $len; $i++) { + $uni = -1; + $h = ord($str[$i]); + + if ($h <= 0x7F) { + $uni = $h; + } + elseif ($h >= 0xC2) { + if (($h <= 0xDF) && ($i < $len - 1)) { + $uni = ($h & 0x1F) << 6 | (ord($str[++$i]) & 0x3F); + } + elseif (($h <= 0xEF) && ($i < $len - 2)) { + $uni = ($h & 0x0F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F); + } + elseif (($h <= 0xF4) && ($i < $len - 3)) { + $uni = ($h & 0x0F) << 18 | (ord($str[++$i]) & 0x3F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F); + } + } + + if ($uni >= 0) { + $out[] = $uni; + } + } + + return $out; + } + + function getUnicodeCharMap() { + $subtable = null; + foreach ($this->getData("cmap", "subtables") as $_subtable) { + if ($_subtable["platformID"] == 0 || $_subtable["platformID"] == 3 && $_subtable["platformSpecificID"] == 1) { + $subtable = $_subtable; + break; + } + } + + if ($subtable) { + return $subtable["glyphIndexArray"]; + } + + return null; + } + + function setSubset($subset) { + if (!is_array($subset)) { + $subset = $this->utf8toUnicode($subset); + } + + $subset = array_unique($subset); + + $glyphIndexArray = $this->getUnicodeCharMap(); + + if (!$glyphIndexArray) { + return; + } + + $gids = array( + 0, // .notdef + 1, // .null + ); + + foreach ($subset as $code) { + if (!isset($glyphIndexArray[$code])) { + continue; + } + + $gid = $glyphIndexArray[$code]; + $gids[$gid] = $gid; + } + + /** @var glyf $glyf */ + $glyf = $this->getTableObject("glyf"); + $gids = $glyf->getGlyphIDs($gids); + + sort($gids); + + $this->glyph_subset = $gids; + $this->glyph_all = array_values($glyphIndexArray); // FIXME + } + + function getSubset() { + if (empty($this->glyph_subset)) { + return $this->glyph_all; + } + + return $this->glyph_subset; + } + + function encode($tags = array()) { + if (!self::$raw) { + $tags = array_merge(array("head", "hhea", "cmap", "hmtx", "maxp", "glyf", "loca", "name", "post"), $tags); + } + else { + $tags = array_keys($this->directory); + } + + $num_tables = count($tags); + $n = 16; // @todo + + Font::d("Tables : " . implode(", ", $tags)); + + /** @var DirectoryEntry[] $entries */ + $entries = array(); + foreach ($tags as $tag) { + if (!isset($this->directory[$tag])) { + Font::d(" >> '$tag' table doesn't exist"); + continue; + } + + $entries[$tag] = $this->directory[$tag]; + } + + $this->header->data["numTables"] = $num_tables; + $this->header->encode(); + + $directory_offset = $this->pos(); + $offset = $directory_offset + $num_tables * $n; + $this->seek($offset); + + $i = 0; + foreach ($entries as $entry) { + $entry->encode($directory_offset + $i * $n); + $i++; + } + } + + function parseHeader() { + if (!empty($this->header)) { + return; + } + + $this->seek($this->tableOffset); + + $this->header = new Header($this); + $this->header->parse(); + } + + function getFontType(){ + $class_parts = explode("\\", get_class($this)); + return $class_parts[1]; + } + + function parseTableEntries() { + $this->parseHeader(); + + if (!empty($this->directory)) { + return; + } + + if (empty($this->header->data["numTables"])) { + return; + } + + + $type = $this->getFontType(); + $class = "FontLib\\$type\\TableDirectoryEntry"; + + for ($i = 0; $i < $this->header->data["numTables"]; $i++) { + /** @var TableDirectoryEntry $entry */ + $entry = new $class($this); + $entry->parse(); + + $this->directory[$entry->tag] = $entry; + } + } + + function normalizeFUnit($value, $base = 1000) { + return round($value * ($base / $this->getData("head", "unitsPerEm"))); + } + + protected function readTable($tag) { + $this->parseTableEntries(); + + if (!self::$raw) { + $name_canon = preg_replace("/[^a-z0-9]/", "", strtolower($tag)); + + $class = "FontLib\\Table\\Type\\$name_canon"; + + if (!isset($this->directory[$tag]) || !class_exists($class)) { + return; + } + } + else { + $class = "FontLib\\Table\\Table"; + } + + /** @var Table $table */ + $table = new $class($this->directory[$tag]); + $table->parse(); + + $this->data[$tag] = $table; + } + + /** + * @param $name + * + * @return Table + */ + public function getTableObject($name) { + return $this->data[$name]; + } + + public function setTableObject($name, Table $data) { + $this->data[$name] = $data; + } + + public function getData($name, $key = null) { + $this->parseTableEntries(); + + if (empty($this->data[$name])) { + $this->readTable($name); + } + + if (!isset($this->data[$name])) { + return null; + } + + if (!$key) { + return $this->data[$name]->data; + } + else { + return $this->data[$name]->data[$key]; + } + } + + function addDirectoryEntry(DirectoryEntry $entry) { + $this->directory[$entry->tag] = $entry; + } + + function saveAdobeFontMetrics($file, $encoding = null) { + $afm = new AdobeFontMetrics($this); + $afm->write($file, $encoding); + } + + /** + * Get a specific name table string value from its ID + * + * @param int $nameID The name ID + * + * @return string|null + */ + function getNameTableString($nameID) { + /** @var nameRecord[] $records */ + $records = $this->getData("name", "records"); + + if (!isset($records[$nameID])) { + return null; + } + + return $records[$nameID]->string; + } + + /** + * Get font copyright + * + * @return string|null + */ + function getFontCopyright() { + return $this->getNameTableString(name::NAME_COPYRIGHT); + } + + /** + * Get font name + * + * @return string|null + */ + function getFontName() { + return $this->getNameTableString(name::NAME_NAME); + } + + /** + * Get font subfamily + * + * @return string|null + */ + function getFontSubfamily() { + return $this->getNameTableString(name::NAME_SUBFAMILY); + } + + /** + * Get font subfamily ID + * + * @return string|null + */ + function getFontSubfamilyID() { + return $this->getNameTableString(name::NAME_SUBFAMILY_ID); + } + + /** + * Get font full name + * + * @return string|null + */ + function getFontFullName() { + return $this->getNameTableString(name::NAME_FULL_NAME); + } + + /** + * Get font version + * + * @return string|null + */ + function getFontVersion() { + return $this->getNameTableString(name::NAME_VERSION); + } + + /** + * Get font weight + * + * @return string|null + */ + function getFontWeight() { + return $this->getTableObject("OS/2")->data["usWeightClass"]; + } + + /** + * Get font Postscript name + * + * @return string|null + */ + function getFontPostscriptName() { + return $this->getNameTableString(name::NAME_POSTSCRIPT_NAME); + } + + function reduce() { + $names_to_keep = array( + name::NAME_COPYRIGHT, + name::NAME_NAME, + name::NAME_SUBFAMILY, + name::NAME_SUBFAMILY_ID, + name::NAME_FULL_NAME, + name::NAME_VERSION, + name::NAME_POSTSCRIPT_NAME, + ); + + foreach ($this->data["name"]->data["records"] as $id => $rec) { + if (!in_array($id, $names_to_keep)) { + unset($this->data["name"]->data["records"][$id]); + } + } + } +}