Most fonts simply have glyphs that correspond to characters in a particular alphabet and are organized
into a known order so that an
a in Roboto is in the same location as
a in another font. However,
not all fonts are character fonts. It is possible to use fonts as a form of an icon library.
Icon fonts still contain glyphs in a particular order. However, the glyphs do not necessarily correspond
with a known alphabet. So typing an
a in a typical font will display some other character when
switching to one of these icon fonts.
I recently ran into a need to incorporate an icon font into a project. In addition to
the ttf file, this font comes with a
.codepoints file. The
.codepoints file is simply a text file
with lines that map to each glyph in the font. Each line contains a name for the glyph and the 2-byte
hex value that makes that glyph appear.
I want to make it as easy as possible to refer to particular glyphs in the font when using it in the user interface I am building. Rather than storing a dictionary in memory and using a set of known constants to address these values, I prefer to exploit the strongly-typed system in C#. This type of map between a word and a numeric value seems like a good fit for an enum.
The problem now is that I have to manually build an enum for this font and any other font that I may encounter in the future. Why do something manually, when I can automate it instead?
I built a source code generator that reads
.codepoints files in a C# project and then
generates an enum. The project is open-sourced with the MIT license and is available on
GitHub. It is also available as a Nuget package.
With this project I was able to explore the source code generation feature in C#. I also set it up with
a continuous integration and continuous deployment pipeline in AppVeyor. Whenever a commit
is pushed to the
main branch, the pipeline builds, tests, packages, creates a GitHub release, and
uploads to NuGet.