In current font formats, glyph shapes live inside rectangular boxes with vertical and horizontal edges. This is a problem when drawing italic or slanted typefaces, because the angle of the stems and the edges of the glyph box don’t align.

To improve this, modern font editors like RoboFont can display slanted sidebearings in order to make drawing italic typefaces more convenient.

This article describes how to work with Italic Slant in RoboFont, some of the issues which appear, and how to solve them.

Activating italic slant

Two settings are required in order to display slanted sidebearings in RoboFont:

  1. In your font file, the font info must contain the correct italic angle of the font. This setting can be found in the Font Info sheet under General > Dimensions:

    • The default italic angle in a font is 0, which corresponds to the 12 o’clock position.
    • The italic angle’s value is counter-clockwise. So, if your font leans to the right (clockwise), the angle will be negative.
  2. In the Preferences Editor, under Glyphs > Display, the option Display Italic Angle must be turned on:

    Explain what these options mean:

    • Slant Point Coordinates
    • Offset Point Coordinates

When these two conditions are met, the sidebearings of each glyph will appear slanted in the Font Window and in the Glyph Window.

As you’ll see, it’s a lot easier to draw slanted/italic fonts this way!

Issues with Italic Slant

It’s important to remember that the slanted sibearings are just a display helper offered by RoboFont during the design process – the final OpenType font can only have rectangular boxes.

When Italic Slant is activated, the sidebearings in your font will be slanted from the baseline. Suppose that you have placed your italic shapes in the center of the slanted box, so that left and right sidebearings are balanced. Everything will appear to be fine:

The glyph shape appears centered between slanted margins…

However, when the font is generated, the glyph shape will not be centered in its rectangular box.

The problem becomes visible if you turn off the Display Italic Angle option in the Preferences. You can see how the shapes are not really centered between the vertical edges of each glyph box. This is what happens when you generate an OpenType font and use it in any application.

…but it’s actually not centered in the ‘real’ glyph box.

Setting the Italic Slant Offset

The solution to this problem is to set the Italic Slant Offset. This value is used to shift the glyphs horizontally when using the Italic Slant preview, so the glyphs are actually centered between their margins in the generated fonts.

The Italic Slant Offset should be set before you start drawing. If you have started drawing before setting this value, see how to add the offset to your font in the next section (below).

The Italic Slant Offset can be calculated from two other values in your font: the italic angle and the x-height. Here is the calculation in code:

import math
f = CurrentFont()
italicSlantOffset = math.tan(f.info.italicAngle * math.pi / 180) * (f.info.xHeight * 0.5)
print(round(italicSlantOffset))

After you have calculated the Italic Slant Offset, you’ll need to store it in the font. Open the Font Info sheet, and find the appropriate setting under RoboFont > Generate:

The Italic Slant Offset is stored in a custom entry in the font.lib. You can get and set this value with Python:

f = CurrentFont()
print(f.lib["com.typemytype.robofont.italicSlantOffset"])
>>> 0
f.lib["com.typemytype.robofont.italicSlantOffset"] = -40
print(f.lib["com.typemytype.robofont.italicSlantOffset"])
>>> -40

Applying the Italic Slant Offset after drawing

If you started drawing your font with Italic Slant and without setting an Italic Slant Offset, all glyphs in your generated font will be off-center. To fix that after some drawing is done, you’ll need to:

  1. calculate and set the Italic Slant Offset
  2. move all glyphs to the correct centered position

The script below takes care of both steps for you:

import math

'''
fixes fonts with Italic Angle but no Italic Slant Offset
- calculates Italic Slant Offset based on Italic Angle and xHeight
- offsets all glyphs accordingly based on a reference glyph

'''

# ---------
# functions
# ---------

def getFlippedComponents(font):
    flippedComponents = []
    for g in font:
        for component in g.components:
            if component.naked().transformation:
                # flipped horizontal
                if component.naked().transformation[0] == -1:
                    flippedComponents.append(g.name)
                # flipped vertical
                if component.naked().transformation[3] == -1:
                    flippedComponents.append(g.name)
    return list(set(flippedComponents))

def offsetGlyphs(font, baseGlyph, roundOffset=False):

    # calculate offset value with baseGlyph
    baseLeftMargin = (font[baseGlyph].angledLeftMargin + font[baseGlyph].angledRightMargin) / 2.0
    offset = -font[baseGlyph].angledLeftMargin + baseLeftMargin

    # round offset value
    if roundOffset and offset != 0:
        offset = round(offset)

    # get flipped components
    flippedComponents = getFlippedComponents(font)

    # apply offset to all glyphs in font
    if offset and font[baseGlyph].angledLeftMargin and len(font.keys()):

        # get reverse components dict
        componentMap = font.getReverseComponentMapping()

        # apply offset to all glyphs in font
        for glyphName in font.keys():
            font[glyphName].prepareUndo()
            font[glyphName].move((offset, 0))
            font[glyphName].performUndo()

            # if the glyph is used as a component, revert component offset
            for composedGlyph in componentMap.get(glyphName, []):
                for component in font[composedGlyph].components:
                    if component.baseGlyph == glyphName:
                        # make sure it's not a flipped component
                        if glyphName not in flippedComponents:
                            component.move((-offset, 0))

            # done with glyph
            font[glyphName].update()

        # fix flipped components
        for glyphName in flippedComponents:
            for component in font[glyphName].components:
                # offset flipped components twice:
                # baseGlyph offset + offset in the wrong direction
                component.move((offset*2, 0))

                # fix glyphs which use the flipped component as a component
                for composedGlyph in componentMap.get(glyphName, []):
                    for component in font[composedGlyph].components:
                        if component.baseGlyph == glyphName:
                            component.move((-offset, 0))

            # done with glyph
            font[glyphName].update()

# --------------
# run the script
# --------------

font = CurrentFont()

# base glyph for offset calculation (the glyph that should be centered)
baseGlyph = 'H'

# round or not the horizontal offset
roundOffset = False

# calculate the italic slant offset
italicSlantOffset = math.tan(font.info.italicAngle * math.pi / 180) * (font.info.xHeight * 0.5)

# set the italic slant offset in font
font.lib['com.typemytype.robofont.italicSlantOffset'] = round(italicSlantOffset)

# offset all glyphs in font
offsetGlyphs(font, baseGlyph, roundOffset)

The script takes care of the foreground layer only – other layers in the font are not touched.


Based on original contribution by Lukas Schneider.

Last edited on 13/09/2018