2
votes

I am trying to understand the anatomy of a font file, and wondering about how glyphs are mapped to keyboard characters.

As part of that, I am also wondering what you do when you have font glyphs that are not part of unicode, such as with FontAwesome icons. FontAwesome uses them in CSS like this:

.fa4-clock-o:before {
  content: "\f017";
}

If I wanted to let's say type these icons out using the keyboard, not sure what I would need to do to make that possible.

Wondering if I would have to do one of these:

  • Build another font that maps them to ALT keycodes somehow (not sure how ALT codes work in the definition of a font).
  • Build a custom keyboard tool that places the correct CSS class on a div (basically don't use the font file / character mapping at all, just build a keyboard tool from scratch).
  • Some other approach.

Wondering if one could explain how to accomplish this at a medium level of detail (that is, I don't necessarily need to know the implementation specific details of how to do it yet, unless it's straightforward).

2
Try just going to fontawesome.com and clicking on the icons link I guess then. Thanks for letting me know.Lance Pollard

2 Answers

3
votes

A sane icon font offers GSUB ligature substitution, so that if your text contains a sequence of codepoints (like those associated with c + a + r) the font does a remapping to an internal glyph (like the car icon) so while typing, you see this:

c
co
com
comp
compu
comput
compute
💻

You typed "computer", once the font sees that last r it triggers the GSUB rule for c + o + m + p + u + t + e + r -> internal_id_24663 and it shapes the text with that replacement instead.

Of course, if the internal glyph id is exposed through a CMAP table, you can also just access the glyph directly, by just specifying the USHORT that the font will be given to shape. In your example, you're directly specifying your Fontawesome icon by writing out its unicode codepoint using a hex value rather than "a letter": the font uses the (by now defacto standard) platform-agnostic Unicode mapping, and you've asked for the glyph associated with code point 0xF017, which is in the "Private Use Area" block (a range of code points from E0x000` to 0xF8FF that don't have prescribed labels for each point: vendors can put whatever they need in them, and are not guaranteed to resolve to the same glyph between versions).

I've written about font internals, including these parts, over on http://pomax.github.io/CFF-glyphlet-fonts

1
votes

Glyphs are not "mapped to keyboard characters". It's rather the other way around, and it happens in multiple steps:

  1. Your keyboard controller picks up the physical signals that are generated by the movement of the keys, converts them into scancodes, and then sends them to your computer.
  2. Then the component of your operating system that is responsible for the keyboard layout transforms the scancodes into codepoints of the characters. For example, on my current operating system (Linux), the mapping from scancodes to code points is defined in a configuration file somewhere in /usr/share/X11/xkb/symbols. Here is an excerpt from the configuration file:

    key <AD01> { [     q,          Q,    adiaeresis,       Adiaeresis ] };
    key <AD02> { [     w,          W,         aring,            Aring ] };
    key <AD03> { [     e,          E,        eacute,           Eacute ] };
    key <AD04> { [     r,          R,    registered,       registered ] };
    key <AD05> { [     t,          T,         thorn,            THORN ] };
    key <AD06> { [     y,          Y,    udiaeresis,       Udiaeresis ] };
    key <AD07> { [     u,          U,        uacute,           Uacute ] };
    key <AD08> { [     i,          I,        iacute,           Iacute ] };
    key <AD09> { [     o,          O,        oacute,           Oacute ] };
    key <AD10> { [     p,          P,    odiaeresis,       Odiaeresis ] };
    

    For example, it says that the scancode <AD04> is mapped to the letter "r".

  3. The symbols that you type on your keyboard using your layout somehow end up in the memory of some server, and are then served as a part of an HTML-document.

  4. The CSS that accompanies the HTML document specifies that a particular font (e.g. Font Awesome) is to be used.

  5. This particular font specifies that, for example, the unicode code point U+F420 should be rendered as the logo of Angular, this is why you see a hexagonal glyph with an A in your browser.

In this whole pathway, there is no fundamental difference between the Angular logo and any other character. The minor differences are:

  1. The angular logo is not part of the Unicode, that is, the Unicode consortium has not defined a code point for the Angular logo. Instead, a code point U+F420 from a private usage area is used. In this case, "private" means that it is used only by you, by Twitter, and by few hundred million other people (anyone who visits a website that uses Font Awesome implicitly agrees to play on this "private" playground by the rules defined in the font).
  2. There is no predefined keyboard layout that maps scancodes to code points from some obscure private usage area.
  3. There is no hardware that has all those funny logos printed on the key caps (since you probably don't use such symbols all that often, it might be a problem).

If you wanted to type text with such glyphs anyway, you would have to:

  1. Somehow specify that you want to use a font that renders code points from the private usage area as the glyphs that you want (e.g. specify it in the CSS of a webpage)
  2. In order to type it, you would have to define your own keyboard layout. For example on Linux, you could copy-paste some configuration file from /usr/share/X11/xkb/symbols, and modify it accordingly.
  3. When you try to use this layout with an actual keyboard, you will probably need some hints which physical key corresponds to which glyph. E.g. you could put an image of the keyboard layout on the desktop background.