/ node_modules / opentype.js / font-inspector.html
font-inspector.html
  1  <!DOCTYPE html>
  2  <html>
  3  <head>
  4      <title>opentype.js font inspector</title>
  5      <meta name="description" content="A JavaScript library to manipulate the letterforms of text from the browser or node.js.">
  6      <meta charset="utf-8">
  7      <link rel="stylesheet" href="site.css">
  8      <script type="text/javascript" src="dist/opentype.js"></script>
  9  </head>
 10  <body>
 11  <div class="header">
 12      <div class="container">
 13          <h1>opentype.js</h1>
 14          <nav>
 15              <a href="index.html">Home</a>
 16              <a href="font-inspector.html">Font Inspector</a>
 17              <a href="glyph-inspector.html">Glyph Inspector</a>
 18          </nav>
 19          <nav class="right">
 20              <a class="github" href="https://github.com/nodebox/opentype.js">Fork me on GitHub</a>
 21              <a class="gitter" href="https://gitter.im/nodebox/opentype.js">Chat on Gitter</a>
 22          </nav>
 23      </div>
 24  </div>
 25  
 26  <div class="container">
 27  
 28      <div class="explain">
 29          <h1>Font Inspector</h1>
 30          <small>opentype.js is an OpenType and TrueType font parser. Here you can inspect the raw font metadata.</small>
 31      </div>
 32  
 33      <input id="file" type="file">
 34      <span class="info" id="font-name">Roboto-Black</span>
 35      <canvas id="preview" width="940" height="50" class="text"></canvas>
 36      <div id="message"></div>
 37  
 38      <hr>
 39  
 40      <div id="font-data">
 41          <h3 class="collapsed">Font Header table <a href="https://www.microsoft.com/typography/OTSPEC/head.htm" target="_blank">head</a></h3>
 42          <dl id="head-table"><dt>Undefined</dt></dl>
 43  
 44          <h3 class="collapsed">Horizontal Header table <a href="https://www.microsoft.com/typography/OTSPEC/hhea.htm" target="_blank">hhea</a></h3>
 45          <dl id="hhea-table"><dt>Undefined</dt></dl>
 46  
 47          <h3 class="collapsed">Maximum Profile table <a href="https://www.microsoft.com/typography/OTSPEC/maxp.htm" target="_blank">maxp</a></h3>
 48          <dl id="maxp-table"><dt>Undefined</dt></dl>
 49  
 50          <h3 class="collapsed">Naming table <a href="https://www.microsoft.com/typography/OTSPEC/name.htm" target="_blank">name</a></h3>
 51          <dl id="name-table"><dt>Undefined</dt></dl>
 52  
 53          <h3 class="collapsed">OS/2 and Windows Metrics table <a href="https://www.microsoft.com/typography/OTSPEC/os2.htm" target="_blank">OS/2</a></h3>
 54          <dl id="os2-table"><dt>Undefined</dt></dl>
 55  
 56          <h3 class="collapsed">PostScript table <a href="https://www.microsoft.com/typography/OTSPEC/post.htm" target="_blank">post</a></h3>
 57          <dl id="post-table"><dt>Undefined</dt></dl>
 58  
 59          <h3 class="collapsed">Character To Glyph Index Mapping Table <a href="https://www.microsoft.com/typography/OTSPEC/cmap.htm" target="_blank">cmap</a></h3>
 60          <dl id="cmap-table"><dt>Undefined</dt></dl>
 61  
 62          <h3 class="collapsed">Font Variations table <a href="https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6fvar.html" target="_blank">fvar</a></h3>
 63          <dl id="fvar-table"><dt>Undefined</dt></dl>
 64  
 65          <h3 class="collapsed">Metadata table <a href="https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6meta.html" target="_blank">meta</a></h3>
 66          <dl id="meta-table"><dt>Undefined</dt></dl>
 67  
 68          <h3 class="collapsed">Control Value Table <a href="https://www.microsoft.com/typography/OTSPEC/cvt.htm" target="_blank">cvt</a></h3>
 69          <dl id="cvt-table"><dt>Undefined</dt></dl>
 70  
 71          <h3 class="collapsed">CVT Program <a href="https://www.microsoft.com/typography/OTSPEC/prep.htm" target="_blank">prep</a></h3>
 72          <dl id="prep-table"><dt>Undefined</dt></dl>
 73  
 74          <h3 class="collapsed">Font program <a href="https://www.microsoft.com/typography/OTSPEC/fpgm.htm" target="_blank">fpgm</a></h3>
 75          <dl id="fpgm-table"><dt>Undefined</dt></dl>
 76  
 77          <h3 class="collapsed">Glyph Substitution Table <a href="https://www.microsoft.com/typography/OTSPEC/GSUB.htm" target="_blank">GSUB</a></h3>
 78          <dl id="gsub-table"><dt>Undefined</dt></dl>
 79  
 80          <h3 class="collapsed">Kerning <a href="https://www.microsoft.com/typography/otspec/kern.htm" target="_blank">kern</a></h3>
 81          <dl id="kern-table"><dt>Undefined</dt></dl>
 82      </div>
 83  
 84      <hr>
 85  
 86      <div class="explain">
 87          <h1>Free Software</h1>
 88          <p>opentype.js is available on <a href="https://github.com/nodebox/opentype.js">GitHub</a> under the <a href="https://raw.github.com/nodebox/opentype.js/master/LICENSE">MIT License</a>.</p>
 89          <p>Copyright &copy; 2017 Frederik De Bleser.</p>
 90      </div>
 91  
 92      <hr>
 93  </div>
 94  
 95  
 96  <script type="text/javascript">
 97  var font = null;
 98  var fontSize = 32;
 99  var textToRender = 'Grumpy wizards make toxic brew for the evil Queen and Jack.';
100  var previewPath = null;
101  
102  function escapeHtml(unsafe) {
103      return unsafe
104           .replace(/&/g, '&amp;')
105           .replace(/</g, '&lt;')
106           .replace(/>/g, '&gt;')
107           .replace(/\u0022/g, '&quot;')
108           .replace(/\u0027/g, '&#039;');
109  }
110  
111  function enableHighDPICanvas(canvas) {
112      if (typeof canvas === 'string') {
113          canvas = document.getElementById(canvas);
114      }
115      var pixelRatio = window.devicePixelRatio || 1;
116      if (pixelRatio === 1) return;
117      var oldWidth = canvas.width;
118      var oldHeight = canvas.height;
119      canvas.width = oldWidth * pixelRatio;
120      canvas.height = oldHeight * pixelRatio;
121      canvas.style.width = oldWidth + 'px';
122      canvas.style.height = oldHeight + 'px';
123      canvas.getContext('2d').scale(pixelRatio, pixelRatio);
124  }
125  
126  function renderText() {
127      if (!font) return;
128  
129      var previewCanvas = document.getElementById('preview');
130      var previewCtx = previewCanvas.getContext("2d");
131      previewCtx.clearRect(0, 0, previewCanvas.width, previewCanvas.height);
132      font.draw(previewCtx, textToRender, 0, 32, fontSize, {
133          kerning: true,
134          features: {
135              liga: true,
136              rlig: true
137          }
138      });
139  }
140  
141  function showErrorMessage(message) {
142      var el = document.getElementById('message');
143      if (!message || message.trim().length === 0) {
144          el.style.display = 'none';
145      } else {
146          el.style.display = 'block';
147      }
148      el.innerHTML = message;
149  }
150  
151  function sortKeys(dict) {
152      var keys = [];
153      for (var key in dict) {
154          keys.push(key);
155      }
156      keys.sort();
157      return keys;
158  }
159  
160  function displayNames(names) {
161      var html = '';
162      properties = sortKeys(names);
163      for (var i = 0; i < properties.length; i++) {
164          var property = properties[i];
165          html += '<dt>'+escapeHtml(property)+'</dt><dd>';
166          var translations = names[property];
167          var langs = sortKeys(translations);
168          for (var j = 0; j < langs.length; j++) {
169              var lang = langs[j];
170              var esclang = escapeHtml(lang);
171              html += '<span class="langtag">' + esclang
172                  + '</span> <span class="langname" lang=' + esclang + '>'
173                  + escapeHtml(translations[lang]) + '</span> ';
174          }
175          html += '</dd>';
176      }
177  
178      document.getElementById('name-table').innerHTML = html;
179  }
180  
181  function displayFontData() {
182      var html, tablename, table, property, value;
183  
184      for (tablename in font.tables) {
185          table = font.tables[tablename];
186          if (tablename == 'name') {
187              displayNames(table);
188              continue;
189          }
190  
191          html = '';
192          for (property in table) {
193              value = table[property];
194              html += '<dt>'+property+'</dt><dd>';
195              if (Array.isArray(value) && typeof value[0] === 'object') {
196                  html += value.map(function(item) {
197                      return JSON.stringify(item);
198                  }).join('<br>');
199              } else if (typeof value === 'object') {
200                html += JSON.stringify(value);
201              } else if (['created', 'modified'].indexOf(property) > -1) {
202                  var date = new Date(value * 1000);
203                  html += date;
204              }
205              else {
206                  html += value;
207              }
208              html += '</dd>';
209          }
210          var element = document.getElementById(tablename+"-table");
211          if (element) {
212              element.innerHTML = html;
213          }
214      }
215  
216      if(font.kerningPairs) {
217          var element = document.getElementById("kern-table");
218          if (element) {
219              element.innerHTML = '<dt>' + Object.keys(font.kerningPairs).length + ' Pairs</dt><dd>' + JSON.stringify(font.kerningPairs) + '</dd>';
220          }
221      }
222  }
223  
224  function onFontLoaded(font) {
225      window.font = font;
226      renderText();
227      displayFontData();
228  }
229  
230  function onReadFile(e) {
231      document.getElementById('font-name').innerHTML = '';
232      var file = e.target.files[0];
233      var reader = new FileReader();
234      reader.onload = function(e) {
235          try {
236              font = opentype.parse(e.target.result);
237              onFontLoaded(font);
238              showErrorMessage('');
239          } catch (err) {
240              showErrorMessage(err.toString());
241              if (err.stack) console.log(err.stack);
242  	    throw(err);
243          }
244      };
245      reader.onerror = function(err) {
246          showErrorMessage(err.toString());
247      };
248  
249      reader.readAsArrayBuffer(file);
250  }
251  
252  var fontFileName = 'fonts/Roboto-Black.ttf';
253  
254  document.getElementById('font-name').innerHTML = fontFileName.split('/')[1];
255  
256  var fileButton = document.getElementById('file');
257  fileButton.addEventListener('change', onReadFile, false);
258  
259  var tableHeaders = document.getElementById('font-data').getElementsByTagName('h3');
260  for(var i = tableHeaders.length; i--; ) {
261      tableHeaders[i].addEventListener('click', function(e) {
262          e.target.className = (e.target.className === 'collapsed') ? 'expanded' : 'collapsed';
263      }, false);
264  }
265  
266  enableHighDPICanvas('preview');
267  
268  opentype.load(fontFileName, function(err, font) {
269      var amount, glyph, ctx, x, y, fontSize;
270      if (err) {
271          showErrorMessage(err.toString());
272          return;
273      }
274      onFontLoaded(font);
275  });
276  </script>
277  </body>
278  </html>