FontCustom/fontcustom — pull request #175 by jlong (2014-02-01 04:38:53+00:00)
Title: Add additional metrics to make it easier to have different size icon fonts

This pull-request adds four additional settings:

font_design_size: 16 # The size of the original glyphs
font_em: 512 # Scale font up to this size
font_ascent: 448 # Location of font ascent
font_descent: 64 # Location of font descent

These map cleanly to the Fontforge values by the same name. Basically this allows you to have fonts scale correctly for a perfect baseline when the height of the glyphs does not evenly go into 512 (which is a bit of a magic number otherwise).

For example, to get a font that is designed with 18px icons I used these settings:

font_design_size: 18 # Height of original glyphs
font_em: 1800 # Scale the glyphs up to 1800 for more precision
font_ascent: 1600 # Set the ascent 200 from the top (2px)
font_descent: 200 # Set the descent 200 from the bottom (2px)

These metrics also allow us to calculate the precise size of a "pixel" using the following formula:

font_em / font_design_size

Knowing this allows us to solve another problem. It appears that glyphs are centered on the "canvas" regardless of their original position in the SVG. This works out well if the glyph is an even number of pixels (6, 8, 10...) but if it is an odd number of pixels vertical lines will appear blurry because the glyph will not be aligned to perfectly to a pixel grid.

To solve this I've added a bit of code that will shift the glyph over to the left to align with the pixel grid as long as the width of the glyph is an integer number of pixels. So if the glyph is 7 pixels wide on an 18 pixel canvas the left edge of the glyph will be at 5 pixels instead of 5.5 pixels as it would without this code. This only works if the width of the glyph is an integer. So if the width of the glyph is 3.3 pixels (a real number) the left edge will be at 7.35 pixels

I've chosen the integer alignment rule because it seems to be a pretty safe bet that if an icon's width is an integer that it should be aligned to a pixel grid. It works well for all of my own icons.