A selection of scripts to do various things to glyphs.

Move points by a random number of units

Move every point in the current glyph by a random number of units.

from random import randint

# get the current glyph
glyph = CurrentGlyph()

# wrap changes in undo context
with glyph.undo('move points randomly'):

    # loop over all contours in glyph
    for contour in glyph:
        # loop over all points in contour
        for point in contour.points:
            # move point by a random distance
            point.x += randint(-20, 20)
            point.y += randint(-20, 20)

    # update glyph
    glyph.changed()

In RoboFont 1.8, use glyph.update() instead of glyph.changed().

Add anchor to selected glyphs

Add anchors with a given name and vertical position in the selected glyphs.

The horizontal position is calculated as the center of the glyph’s bounding box.

# get the current font
font = CurrentFont()

# define anchor name and y-position
anchorName = 'top'
anchorY = 800

# loop over selected glyphs
for glyph in font.selectedGlyphs:

    # get the glyph bounds (aka glyph box)
    # bounds is either a tuple of (left, bottom, right, top)
    # or None if the glyph has no contours
    bounds = glyph.bounds

    # skip empty glyphs
    if bounds is None:
        continue

    # get the horizontal center
    L, B, R, T = bounds
    anchorX = L + (R - L) * 0.5

    # add anchor to glyph
    with glyph.undo('add anchor'):
        glyph.appendAnchor(anchorName, (anchorX, anchorY))

In RoboFont 1.8, use glyph.box() instead of glyph.bounds().

Drawing inside a glyph with a pen

Draw inside a glyph using a pen.

# get the current font
font = CurrentFont()

# get a glyph
glyph1 = font['a']

# empty the glyph
glyph1.clear()

# get a pen to draw inside the glyph
pen = glyph1.getPen()

# draw a closed Bezier path
pen.moveTo((0, 0))
pen.lineTo((0, 200))
pen.curveTo((50, 150), (150, 150), (200, 200))
pen.lineTo((200, 0))
pen.closePath()

# get another glyph
glyph2 = font['b']
glyph2.clear()

# draw an open Bezier path
pen = glyph2.getPen()
pen.moveTo((0, 0))
pen.lineTo((200, 100))
pen.lineTo((0, 200))
pen.lineTo((200, 300))
pen.endPath()

Rasterizing a glyph

Rasterize a glyph with a given grid size.

converted from robofab.objects.objectsBase.BaseGlyph

def rasterize(glyph, cellSize=50, xMin=None, yMin=None, xMax=None, yMax=None):
    """
    Slice the glyph into a grid based on the given cell size.

    Returns a list of lists containing bool values that indicate the
    black (True) or white (False) value of that particular cell.
    These lists are arranged from top to bottom of the glyph and proceed
    from left to right.

    Warning: This is an expensive operation!

    """

    if xMin is None or yMin is None or xMax is None or yMax is None:
        _xMin, _yMin, _xMax, _yMax = glyph.bounds
        if xMin is None:
            xMin = _xMin
        if yMin is None:
            yMin = _yMin
        if xMax is None:
            xMax = _xMax
        if yMax is None:
            yMax = _yMax

    hitXMax = False
    hitYMin = False
    xSlice = 0
    ySlice = 0
    halfCellSize = cellSize / 2.0
    bitmap = []

    while not hitYMin:
        bitmap.append([])
        yScan = -(ySlice * cellSize) + yMax - halfCellSize
        if yScan < yMin:
            hitYMin = True
        while not hitXMax:
            xScan = (xSlice * cellSize) + xMin - halfCellSize
            if xScan > xMax:
                hitXMax = True
            test = glyph.pointInside((xScan, yScan))
            if test:
                bitmap[-1].append(True)
            else:
                bitmap[-1].append(False)
            xSlice = xSlice + 1
        hitXMax = False
        xSlice = 0
        ySlice = ySlice + 1

    return bitmap

# get the current font
font = CurrentFont()

# get the current glyph
glyph = CurrentGlyph()

# define the rasterization area
cellSize = 40
xMin = 0
yMin = font.info.descender
xMax = glyph.width
yMax = font.info.ascender

# rasterize the current glyph
bitmap = rasterize(glyph, cellSize, xMin, yMin, xMax, yMax)

# preview the output as text
for line in bitmap:
    for bit in line:
        if bit:
            print('O ', end='')
        else:
            print('- ', end='')
    print()

Get glif path for glyph

In UFO3 fonts, each glyph is stored in a single glif file inside a layer folder.

The script below returns the .glif path for the current glyph.

import os
from fontTools.ufoLib import UFOReader

def getGlifPath(glyph):
    reader = UFOReader(glyph.font.path)
    # get glyphset for currrent layer
    glyphSet = reader.getGlyphSet(glyph.layer.name)
    # get filename for glyph name
    glifName = glyphSet.glyphNameToFileName(glyph.name, None)
    # glif path = ufo path + layer folder + glif file
    glifPath = os.path.join(glyph.font.path, glyphSet.dirName, glifName)
    return glifPath

print(getGlifPath(CurrentGlyph()))
/myFolder/myFont.ufo/glyphs/one.glif

Relevant threads from the RoboFont forum

Last edited on 01/09/2021