A collection of scripts to do things to glyphs.

Move points by a random amount of units

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

from random import randint

# get the current glyph
glyph = CurrentGlyph()

# set undo state
glyph.prepareUndo('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()

# restore undo state
glyph.performUndo()

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

Add anchor to selected glyphs

'''Add anchors with a given name and height in the selected glyphs.'''

# 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
    glyph.prepareUndo('add anchor')
    glyph.appendAnchor(anchorName, (anchorX, anchorY))
    glyph.performUndo()

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.
Transforms an outline shape into an array of boolean pixels.

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()
Last edited on 31/01/2019