Font_TrueType

TrueType font file.

Defined (1)

The class is defined in the following location(s).

/lib/dompdf/lib/php-font-lib/classes/Font_TrueType.php  
  1. class Font_TrueType extends Font_Binary_Stream { 
  2. /** 
  3. * @var Font_TrueType_Header 
  4. */ 
  5. public $header = array(); 
  6.  
  7. private $tableOffset = 0; // Used for TTC 
  8.  
  9. private static $raw = false; 
  10.  
  11. protected $directory = array(); 
  12. protected $data = array(); 
  13.  
  14. protected $glyph_subset = array(); 
  15.  
  16. public $glyph_all = array(); 
  17.  
  18. static $macCharNames = array( 
  19. ".notdef", ".null", "CR",  
  20. "space", "exclam", "quotedbl", "numbersign",  
  21. "dollar", "percent", "ampersand", "quotesingle",  
  22. "parenleft", "parenright", "asterisk", "plus",  
  23. "comma", "hyphen", "period", "slash",  
  24. "zero", "one", "two", "three",  
  25. "four", "five", "six", "seven",  
  26. "eight", "nine", "colon", "semicolon",  
  27. "less", "equal", "greater", "question",  
  28. "at", "A", "B", "C", "D", "E", "F", "G",  
  29. "H", "I", "J", "K", "L", "M", "N", "O",  
  30. "P", "Q", "R", "S", "T", "U", "V", "W",  
  31. "X", "Y", "Z", "bracketleft",  
  32. "backslash", "bracketright", "asciicircum", "underscore",  
  33. "grave", "a", "b", "c", "d", "e", "f", "g",  
  34. "h", "i", "j", "k", "l", "m", "n", "o",  
  35. "p", "q", "r", "s", "t", "u", "v", "w",  
  36. "x", "y", "z", "braceleft",  
  37. "bar", "braceright", "asciitilde", "Adieresis",  
  38. "Aring", "Ccedilla", "Eacute", "Ntilde",  
  39. "Odieresis", "Udieresis", "aacute", "agrave",  
  40. "acircumflex", "adieresis", "atilde", "aring",  
  41. "ccedilla", "eacute", "egrave", "ecircumflex",  
  42. "edieresis", "iacute", "igrave", "icircumflex",  
  43. "idieresis", "ntilde", "oacute", "ograve",  
  44. "ocircumflex", "odieresis", "otilde", "uacute",  
  45. "ugrave", "ucircumflex", "udieresis", "dagger",  
  46. "degree", "cent", "sterling", "section",  
  47. "bullet", "paragraph", "germandbls", "registered",  
  48. "copyright", "trademark", "acute", "dieresis",  
  49. "notequal", "AE", "Oslash", "infinity",  
  50. "plusminus", "lessequal", "greaterequal", "yen",  
  51. "mu", "partialdiff", "summation", "product",  
  52. "pi", "integral", "ordfeminine", "ordmasculine",  
  53. "Omega", "ae", "oslash", "questiondown",  
  54. "exclamdown", "logicalnot", "radical", "florin",  
  55. "approxequal", "increment", "guillemotleft", "guillemotright",  
  56. "ellipsis", "nbspace", "Agrave", "Atilde",  
  57. "Otilde", "OE", "oe", "endash",  
  58. "emdash", "quotedblleft", "quotedblright", "quoteleft",  
  59. "quoteright", "divide", "lozenge", "ydieresis",  
  60. "Ydieresis", "fraction", "currency", "guilsinglleft",  
  61. "guilsinglright", "fi", "fl", "daggerdbl",  
  62. "periodcentered", "quotesinglbase", "quotedblbase", "perthousand",  
  63. "Acircumflex", "Ecircumflex", "Aacute", "Edieresis",  
  64. "Egrave", "Iacute", "Icircumflex", "Idieresis",  
  65. "Igrave", "Oacute", "Ocircumflex", "applelogo",  
  66. "Ograve", "Uacute", "Ucircumflex", "Ugrave",  
  67. "dotlessi", "circumflex", "tilde", "macron",  
  68. "breve", "dotaccent", "ring", "cedilla",  
  69. "hungarumlaut", "ogonek", "caron", "Lslash",  
  70. "lslash", "Scaron", "scaron", "Zcaron",  
  71. "zcaron", "brokenbar", "Eth", "eth",  
  72. "Yacute", "yacute", "Thorn", "thorn",  
  73. "minus", "multiply", "onesuperior", "twosuperior",  
  74. "threesuperior", "onehalf", "onequarter", "threequarters",  
  75. "franc", "Gbreve", "gbreve", "Idot",  
  76. "Scedilla", "scedilla", "Cacute", "cacute",  
  77. "Ccaron", "ccaron", "dmacron" 
  78. ); 
  79.  
  80. function getTable() { 
  81. $this->parseTableEntries(); 
  82. return $this->directory; 
  83.  
  84. function setTableOffset($offset) { 
  85. $this->tableOffset = $offset; 
  86.  
  87. function parse() { 
  88. $this->parseTableEntries(); 
  89.  
  90. $this->data = array(); 
  91.  
  92. foreach($this->directory as $tag => $table) { 
  93. if (empty($this->data[$tag])) { 
  94. $this->readTable($tag); 
  95.  
  96. function utf8toUnicode($str) { 
  97. $len = strlen($str); 
  98. $out = array(); 
  99.  
  100. for ($i = 0; $i < $len; $i++) { 
  101. $uni = -1; 
  102. $h = ord($str[$i]); 
  103.  
  104. if ( $h <= 0x7F ) { 
  105. $uni = $h; 
  106. elseif ( $h >= 0xC2 ) { 
  107. if ( ($h <= 0xDF) && ($i < $len -1) ) 
  108. $uni = ($h & 0x1F) << 6 | (ord($str[++$i]) & 0x3F); 
  109. elseif ( ($h <= 0xEF) && ($i < $len -2) ) 
  110. $uni = ($h & 0x0F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F); 
  111. elseif ( ($h <= 0xF4) && ($i < $len -3) ) 
  112. $uni = ($h & 0x0F) << 18 | (ord($str[++$i]) & 0x3F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F); 
  113.  
  114. if ($uni >= 0) { 
  115. $out[] = $uni; 
  116.  
  117. return $out; 
  118.  
  119. function getUnicodeCharMap() { 
  120. $subtable = null; 
  121. foreach($this->getData("cmap", "subtables") as $_subtable) { 
  122. if ($_subtable["platformID"] == 0 || $_subtable["platformID"] == 3 && $_subtable["platformSpecificID"] == 1) { 
  123. $subtable = $_subtable; 
  124. break; 
  125.  
  126. if ($subtable) { 
  127. return $subtable["glyphIndexArray"]; 
  128.  
  129. return null; 
  130.  
  131. function setSubset($subset) { 
  132. if ( !is_array($subset) ) { 
  133. $subset = $this->utf8toUnicode($subset); 
  134.  
  135. $subset = array_unique($subset); 
  136.  
  137. $glyphIndexArray = $this->getUnicodeCharMap(); 
  138.  
  139. if (!$glyphIndexArray) { 
  140. return; 
  141.  
  142. $gids = array( 
  143. 0, // .notdef 
  144. 1, // .null 
  145. ); 
  146.  
  147. foreach($subset as $code) { 
  148. if (!isset($glyphIndexArray[$code])) { 
  149. continue; 
  150.  
  151. $gid = $glyphIndexArray[$code]; 
  152. $gids[$gid] = $gid; 
  153.  
  154. /** @var Font_Table_glyf $glyf */ 
  155. $glyf = $this->getTableObject("glyf"); 
  156. $gids = $glyf->getGlyphIDs($gids); 
  157.  
  158. sort($gids); 
  159.  
  160. $this->glyph_subset = $gids; 
  161. $this->glyph_all = array_values($glyphIndexArray); // FIXME 
  162.  
  163. function getSubset() { 
  164. if (empty($this->glyph_subset)) { 
  165. return $this->glyph_all; 
  166.  
  167. return $this->glyph_subset; 
  168.  
  169. function encode($tags = array()) { 
  170. if (!self::$raw) { 
  171. $tags = array_merge(array("head", "hhea", "cmap", "hmtx", "maxp", "glyf", "loca", "name", "post"), $tags); 
  172. else { 
  173. $tags = array_keys($this->directory); 
  174.  
  175. $num_tables = count($tags); 
  176. $n = 16;// @todo 
  177.  
  178. Font::d("Tables : ".implode(", ", $tags)); 
  179.  
  180. /** @var Font_Table_Directory_Entry[] $entries */ 
  181. $entries = array(); 
  182. foreach($tags as $tag) { 
  183. if (!isset($this->directory[$tag])) { 
  184. Font::d(" >> '$tag' table doesn't exist"); 
  185. continue; 
  186.  
  187. $entries[$tag] = $this->directory[$tag]; 
  188.  
  189. $this->header->data["numTables"] = $num_tables; 
  190. $this->header->encode(); 
  191.  
  192. $directory_offset = $this->pos(); 
  193. $offset = $directory_offset + $num_tables * $n; 
  194. $this->seek($offset); 
  195.  
  196. $i = 0; 
  197. foreach($entries as $entry) { 
  198. $entry->encode($directory_offset + $i * $n); 
  199. $i++; 
  200.  
  201. function parseHeader() { 
  202. if (!empty($this->header)) { 
  203. return; 
  204.  
  205. $this->seek($this->tableOffset); 
  206.  
  207. $this->header = new Font_TrueType_Header($this); 
  208. $this->header->parse(); 
  209.  
  210. function parseTableEntries() { 
  211. $this->parseHeader(); 
  212.  
  213. if (!empty($this->directory)) { 
  214. return; 
  215.  
  216. if (empty($this->header->data["numTables"])) { 
  217. return; 
  218.  
  219. $class = get_class($this)."_Table_Directory_Entry"; 
  220.  
  221. for($i = 0; $i < $this->header->data["numTables"]; $i++) { 
  222. /** @var Font_Table_Directory_Entry $entry */ 
  223. $entry = new $class($this); 
  224. $entry->parse(); 
  225.  
  226. $this->directory[$entry->tag] = $entry; 
  227.  
  228. function normalizeFUnit($value, $base = 1000) { 
  229. return round($value * ($base / $this->getData("head", "unitsPerEm"))); 
  230.  
  231. protected function readTable($tag) { 
  232. $this->parseTableEntries(); 
  233.  
  234. if (!self::$raw) { 
  235. $name_canon = preg_replace("/[^a-z0-9]/", "", strtolower($tag)); 
  236. $class_file = dirname(__FILE__)."/Font_Table_$name_canon.php"; 
  237.  
  238. if (!isset($this->directory[$tag]) || !file_exists($class_file)) { 
  239. return; 
  240.  
  241. /** @noinspection PhpIncludeInspection */ 
  242. require_once $class_file; 
  243. $class = "Font_Table_$name_canon"; 
  244. else { 
  245. $class = "Font_Table"; 
  246.  
  247. /** @var Font_Table $table */ 
  248. $table = new $class($this->directory[$tag]); 
  249. $table->parse(); 
  250.  
  251. $this->data[$tag] = $table; 
  252.  
  253. /** 
  254. * @param $name 
  255. * @return Font_Table 
  256. */ 
  257. public function getTableObject($name) { 
  258. return $this->data[$name]; 
  259.  
  260. public function setTableObject($name, Font_Table $data) { 
  261. $this->data[$name] = $data; 
  262.  
  263. public function getData($name, $key = null) { 
  264. $this->parseTableEntries(); 
  265.  
  266. if (empty($this->data[$name])) { 
  267. $this->readTable($name); 
  268.  
  269. if (!isset($this->data[$name])) { 
  270. return null; 
  271.  
  272. if (!$key) { 
  273. return $this->data[$name]->data; 
  274. else { 
  275. return $this->data[$name]->data[$key]; 
  276.  
  277. function addDirectoryEntry(Font_Table_Directory_Entry $entry) { 
  278. $this->directory[$entry->tag] = $entry; 
  279.  
  280. function saveAdobeFontMetrics($file, $encoding = null) { 
  281. $afm = new Adobe_Font_Metrics($this); 
  282. $afm->write($file, $encoding); 
  283.  
  284. /** 
  285. * Get a specific name table string value from its ID 
  286. * @param int $nameID The name ID 
  287. * @return string|null 
  288. */ 
  289. function getNameTableString($nameID) { 
  290. /** @var Font_Table_name_Record[] $records */ 
  291. $records = $this->getData("name", "records"); 
  292.  
  293. if (!isset($records[$nameID])) { 
  294. return null; 
  295.  
  296. return $records[$nameID]->string; 
  297.  
  298. /** 
  299. * Get font copyright 
  300. * @return string|null 
  301. */ 
  302. function getFontCopyright() { 
  303. return $this->getNameTableString(Font_Table_name::NAME_COPYRIGHT); 
  304.  
  305. /** 
  306. * Get font name 
  307. * @return string|null 
  308. */ 
  309. function getFontName() { 
  310. return $this->getNameTableString(Font_Table_name::NAME_NAME); 
  311.  
  312. /** 
  313. * Get font subfamily 
  314. * @return string|null 
  315. */ 
  316. function getFontSubfamily() { 
  317. return $this->getNameTableString(Font_Table_name::NAME_SUBFAMILY); 
  318.  
  319. /** 
  320. * Get font subfamily ID 
  321. * @return string|null 
  322. */ 
  323. function getFontSubfamilyID() { 
  324. return $this->getNameTableString(Font_Table_name::NAME_SUBFAMILY_ID); 
  325.  
  326. /** 
  327. * Get font full name 
  328. * @return string|null 
  329. */ 
  330. function getFontFullName() { 
  331. return $this->getNameTableString(Font_Table_name::NAME_FULL_NAME); 
  332.  
  333. /** 
  334. * Get font version 
  335. * @return string|null 
  336. */ 
  337. function getFontVersion() { 
  338. return $this->getNameTableString(Font_Table_name::NAME_VERSION); 
  339.  
  340. /** 
  341. * Get font weight 
  342. * @return string|null 
  343. */ 
  344. function getFontWeight() { 
  345. return $this->getTableObject("OS/2")->data["usWeightClass"]; 
  346.  
  347. /** 
  348. * Get font Postscript name 
  349. * @return string|null 
  350. */ 
  351. function getFontPostscriptName() { 
  352. return $this->getNameTableString(Font_Table_name::NAME_POSTSCRIPT_NAME); 
  353.  
  354. function reduce() { 
  355. $names_to_keep = array( 
  356. Font_Table_name::NAME_COPYRIGHT,  
  357. Font_Table_name::NAME_NAME,  
  358. Font_Table_name::NAME_SUBFAMILY,  
  359. Font_Table_name::NAME_SUBFAMILY_ID,  
  360. Font_Table_name::NAME_FULL_NAME,  
  361. Font_Table_name::NAME_VERSION,  
  362. Font_Table_name::NAME_POSTSCRIPT_NAME,  
  363. ); 
  364.  
  365. foreach($this->data["name"]->data["records"] as $id => $rec) { 
  366. if (!in_array($id, $names_to_keep)) { 
  367. unset($this->data["name"]->data["records"][$id]);