admin管理员组

文章数量:1356892

TL/DR: How to display each glyph from a font file using some parsing method that shows all of the characters.

I am trying to build a glyph viewer for one of several fonts I want to show on a page.

Currently I have this codesandbox (this is cramped so there is a full page version here)

Here is my JS:

import opentype from "opentype.js";
const htmlElem = document.querySelector("html");

const fontPath = "/src/resources";

const fontMap = (fontName) => {
  const url = `${fontPath}/${fontName}`;
  const buffer = fetch(url).then((res) => res.arrayBuffer());

  buffer.then((data) => {
    const wrapper = htmlElem.querySelector(".characters ul");
    const font = opentype.parse(data);
    const glyphs = font.glyphs.glyphs;
    for (const [key, value] of Object.entries(glyphs)) {
      if (value.name !== null) {
        const template = `<li>${value.name}</li>`;
        wrapper.insertAdjacentHTML("beforeend", template);
        console.log(value);
      }
    }
  });
};

fontMap("Calluna-Regular.otf");

When I log each glyph I get quite a lot of data about the element, however I want to know how to access it on the page using the correct property.

Currently trying to access item.name which works fine for 'A', 'B', 'C' etc, but numbers are named in full 'one', 'two', etc. And punctuation marks, I guess name makes sense.

I tried adding a prefix to output as html entities, like <li>&${value.name};</li> but of course that will prefix the standard 'A' with an '&'.

Is there a universal way to parse each character and use some encoding to display each item on the page? Hex maybe but not transform the simple characters. The other thing I wondered is whether certain glyphs have particular properties that distinguish them. I think the unicode property is the only one I can access that will help me.

Also in this font the letter 'A' has unicode: 64 in the mapping but the universal unicode character for 'A' is U+0041 (or is that already converted using some system), I don't know if this is some peculiarity of the font file.

Any help greatly appreciated.

TL/DR: How to display each glyph from a font file using some parsing method that shows all of the characters.

I am trying to build a glyph viewer for one of several fonts I want to show on a page.

Currently I have this codesandbox (this is cramped so there is a full page version here)

Here is my JS:

import opentype from "opentype.js";
const htmlElem = document.querySelector("html");

const fontPath = "/src/resources";

const fontMap = (fontName) => {
  const url = `${fontPath}/${fontName}`;
  const buffer = fetch(url).then((res) => res.arrayBuffer());

  buffer.then((data) => {
    const wrapper = htmlElem.querySelector(".characters ul");
    const font = opentype.parse(data);
    const glyphs = font.glyphs.glyphs;
    for (const [key, value] of Object.entries(glyphs)) {
      if (value.name !== null) {
        const template = `<li>${value.name}</li>`;
        wrapper.insertAdjacentHTML("beforeend", template);
        console.log(value);
      }
    }
  });
};

fontMap("Calluna-Regular.otf");

When I log each glyph I get quite a lot of data about the element, however I want to know how to access it on the page using the correct property.

Currently trying to access item.name which works fine for 'A', 'B', 'C' etc, but numbers are named in full 'one', 'two', etc. And punctuation marks, I guess name makes sense.

I tried adding a prefix to output as html entities, like <li>&${value.name};</li> but of course that will prefix the standard 'A' with an '&'.

Is there a universal way to parse each character and use some encoding to display each item on the page? Hex maybe but not transform the simple characters. The other thing I wondered is whether certain glyphs have particular properties that distinguish them. I think the unicode property is the only one I can access that will help me.

Also in this font the letter 'A' has unicode: 64 in the mapping but the universal unicode character for 'A' is U+0041 (or is that already converted using some system), I don't know if this is some peculiarity of the font file.

Any help greatly appreciated.

Share Improve this question asked Mar 30 at 11:17 lharbylharby 3,2776 gold badges26 silver badges65 bronze badges 5
  • At least start using await instead of .then chaining. – Mike 'Pomax' Kamermans Commented Mar 30 at 21:28
  • @Mike'Pomax'Kamermans LOL, that code is from the opentypejs documentation, but I actually prefer the chaining syntax. – lharby Commented Mar 31 at 6:57
  • Thanks @imhvost I can't reply beneath your answer for some reason, so I hope you see this. Did not know of the fromCharCode function, super useful, thank you. – lharby Commented Mar 31 at 7:29
  • 1 Be aware that most alternate glyphs e.g ligatures or stylistic variants don't have a unicode as they are controlled and substituted by Opentype feature definitions. So you won't get a complete glyph map – herrstrietzel Commented Mar 31 at 16:39
  • @herrstrietzel interestingly this leads me to another question, but I am not sure if this is right forum. I am currently trying to reach out on mastodon. Might be back here if needed. – lharby Commented Mar 31 at 17:20
Add a comment  | 

1 Answer 1

Reset to default 2

You have a specific unicode character in the unicode value, so convert it using String.fromCharCode():

const fontMap = (fontName) => {
  const url = `${fontPath}/${fontName}`;
  const buffer = fetch(url).then((res) => res.arrayBuffer());

  buffer.then((data) => {
    const wrapper = htmlElem.querySelector(".characters ul");
    const font = opentype.parse(data);
    const glyphs = font.glyphs.glyphs;
    for (const [key, value] of Object.entries(glyphs)) {
      if (value.name !== null) {
        const template = `<li>${String.fromCharCode(value.unicodes)}</li>`;
        wrapper.insertAdjacentHTML("beforeend", template);
        console.log(value);
      }
    }
  });
};

本文标签: javascriptUse opentypejs to loop through all glyphs in a font and output them to the pageStack Overflow