Geen omschrijving

AdobeFontMetrics.php 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. /**
  3. * @package php-font-lib
  4. * @link https://github.com/PhenX/php-font-lib
  5. * @author Fabien Ménager <fabien.menager@gmail.com>
  6. * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
  7. */
  8. namespace FontLib;
  9. use FontLib\Table\Type\name;
  10. use FontLib\TrueType\File;
  11. /**
  12. * Adobe Font Metrics file creation utility class.
  13. *
  14. * @package php-font-lib
  15. */
  16. class AdobeFontMetrics {
  17. private $f;
  18. /**
  19. * @var File
  20. */
  21. private $font;
  22. function __construct(File $font) {
  23. $this->font = $font;
  24. }
  25. function write($file, $encoding = null) {
  26. $map_data = array();
  27. if ($encoding) {
  28. $encoding = preg_replace("/[^a-z0-9-_]/", "", $encoding);
  29. $map_file = dirname(__FILE__) . "/../maps/$encoding.map";
  30. if (!file_exists($map_file)) {
  31. throw new \Exception("Unknown encoding ($encoding)");
  32. }
  33. $map = new EncodingMap($map_file);
  34. $map_data = $map->parse();
  35. }
  36. $this->f = fopen($file, "w+");
  37. $font = $this->font;
  38. $this->startSection("FontMetrics", 4.1);
  39. $this->addPair("Notice", "Converted by PHP-font-lib");
  40. $this->addPair("Comment", "https://github.com/PhenX/php-font-lib");
  41. $encoding_scheme = ($encoding ? $encoding : "FontSpecific");
  42. $this->addPair("EncodingScheme", $encoding_scheme);
  43. $records = $font->getData("name", "records");
  44. foreach ($records as $id => $record) {
  45. if (!isset(name::$nameIdCodes[$id]) || preg_match("/[\r\n]/", $record->string)) {
  46. continue;
  47. }
  48. $this->addPair(name::$nameIdCodes[$id], $record->string);
  49. }
  50. $os2 = $font->getData("OS/2");
  51. $this->addPair("Weight", ($os2["usWeightClass"] > 400 ? "Bold" : "Medium"));
  52. $post = $font->getData("post");
  53. $this->addPair("ItalicAngle", $post["italicAngle"]);
  54. $this->addPair("IsFixedPitch", ($post["isFixedPitch"] ? "true" : "false"));
  55. $this->addPair("UnderlineThickness", $font->normalizeFUnit($post["underlineThickness"]));
  56. $this->addPair("UnderlinePosition", $font->normalizeFUnit($post["underlinePosition"]));
  57. $hhea = $font->getData("hhea");
  58. if (isset($hhea["ascent"])) {
  59. $this->addPair("FontHeightOffset", $font->normalizeFUnit($hhea["lineGap"]));
  60. $this->addPair("Ascender", $font->normalizeFUnit($hhea["ascent"]));
  61. $this->addPair("Descender", $font->normalizeFUnit($hhea["descent"]));
  62. }
  63. else {
  64. $this->addPair("FontHeightOffset", $font->normalizeFUnit($os2["typoLineGap"]));
  65. $this->addPair("Ascender", $font->normalizeFUnit($os2["typoAscender"]));
  66. $this->addPair("Descender", -abs($font->normalizeFUnit($os2["typoDescender"])));
  67. }
  68. $head = $font->getData("head");
  69. $this->addArray("FontBBox", array(
  70. $font->normalizeFUnit($head["xMin"]),
  71. $font->normalizeFUnit($head["yMin"]),
  72. $font->normalizeFUnit($head["xMax"]),
  73. $font->normalizeFUnit($head["yMax"]),
  74. ));
  75. $glyphIndexArray = $font->getUnicodeCharMap();
  76. if ($glyphIndexArray) {
  77. $hmtx = $font->getData("hmtx");
  78. $names = $font->getData("post", "names");
  79. $this->startSection("CharMetrics", count($hmtx));
  80. if ($encoding) {
  81. foreach ($map_data as $code => $value) {
  82. list($c, $name) = $value;
  83. if (!isset($glyphIndexArray[$c])) {
  84. continue;
  85. }
  86. $g = $glyphIndexArray[$c];
  87. if (!isset($hmtx[$g])) {
  88. $hmtx[$g] = $hmtx[0];
  89. }
  90. $this->addMetric(array(
  91. "C" => ($code > 255 ? -1 : $code),
  92. "WX" => $font->normalizeFUnit($hmtx[$g][0]),
  93. "N" => $name,
  94. ));
  95. }
  96. }
  97. else {
  98. foreach ($glyphIndexArray as $c => $g) {
  99. if (!isset($hmtx[$g])) {
  100. $hmtx[$g] = $hmtx[0];
  101. }
  102. $this->addMetric(array(
  103. "U" => $c,
  104. "WX" => $font->normalizeFUnit($hmtx[$g][0]),
  105. "N" => (isset($names[$g]) ? $names[$g] : sprintf("uni%04x", $c)),
  106. "G" => $g,
  107. ));
  108. }
  109. }
  110. $this->endSection("CharMetrics");
  111. $kern = $font->getData("kern", "subtable");
  112. $tree = is_array($kern) ? $kern["tree"] : null;
  113. if (!$encoding && is_array($tree)) {
  114. $this->startSection("KernData");
  115. $this->startSection("KernPairs", count($tree, COUNT_RECURSIVE) - count($tree));
  116. foreach ($tree as $left => $values) {
  117. if (!is_array($values)) {
  118. continue;
  119. }
  120. if (!isset($glyphIndexArray[$left])) {
  121. continue;
  122. }
  123. $left_gid = $glyphIndexArray[$left];
  124. if (!isset($names[$left_gid])) {
  125. continue;
  126. }
  127. $left_name = $names[$left_gid];
  128. $this->addLine("");
  129. foreach ($values as $right => $value) {
  130. if (!isset($glyphIndexArray[$right])) {
  131. continue;
  132. }
  133. $right_gid = $glyphIndexArray[$right];
  134. if (!isset($names[$right_gid])) {
  135. continue;
  136. }
  137. $right_name = $names[$right_gid];
  138. $this->addPair("KPX", "$left_name $right_name $value");
  139. }
  140. }
  141. $this->endSection("KernPairs");
  142. $this->endSection("KernData");
  143. }
  144. }
  145. $this->endSection("FontMetrics");
  146. }
  147. function addLine($line) {
  148. fwrite($this->f, "$line\n");
  149. }
  150. function addPair($key, $value) {
  151. $this->addLine("$key $value");
  152. }
  153. function addArray($key, $array) {
  154. $this->addLine("$key " . implode(" ", $array));
  155. }
  156. function addMetric($data) {
  157. $array = array();
  158. foreach ($data as $key => $value) {
  159. $array[] = "$key $value";
  160. }
  161. $this->addLine(implode(" ; ", $array));
  162. }
  163. function startSection($name, $value = "") {
  164. $this->addLine("Start$name $value");
  165. }
  166. function endSection($name) {
  167. $this->addLine("End$name");
  168. }
  169. }