Move points by a random amount of units

This script messes up with your outlines by moving every point by a random amount of units. While not very useful, it shows randomness and Undo in action.

from random import randint

glyph = CurrentGlyph()
glyph.prepareUndo('move points randomly')

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

glyph.changed()
glyph.performUndo()

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

Add anchor to selected glyphs

This script adds top anchors at the specified y-position in the selected glyphs.

The x-position is calculated as the middle of each glyphs’s bounding box.

# get the current font
f = CurrentFont()

# define name and position of the anchor
anchorName = 'top'
y = 530

# iterate over the names of selected glyphs
for glyphName in f.selection:

    # get the glyph
    g = f[glyphName]

    # get the bounds
    # bounds is either a tuple of 4 values or `None` if there is not contour
    bounds = g.bounds

    # check if bounds is not None
    if bounds:
        # define x-position as the middle of the glyph's bounding box
        xMiddle = g.bounds[0] + (g.bounds[2] - g.bounds[0]) * 0.5

        # add anchor to glyph
        g.prepareUndo('add anchor')
        g.appendAnchor(anchorName, (xMiddle, y))
        g.performUndo()

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

Drawing inside a glyph with a pen

This example shows how to draw into a glyph with code – using a Pen object.

# get a font
f = CurrentFont()

# get a glyph
g = f['a']

# empty the glyph
g.clear()

# get a pen to draw in the glyph
pen = g.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
g2 = f['b']
g2.clear()

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

Rasterizing a glyph shape

The script below shows a simple glyph rasterizer using glyph.pointInside().

# ported 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()

- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - O O - -
- - - - - - O O O O O - O O O O -
- - - - O O O O O O O O O - - - -
- - - O O O O - - - O O O O - - -
- - - O O O - - - - O O O O - - -
- - O O O O - - - - - O O O - - -
- - O O O O - - - - - O O O - - -
- - - O O O - - - - O O O O - - -
- - - O O O O - - - O O O - - - -
- - - - - O O O O O O O - - - - -
- - - - - - - - O - - - - - - - -
- - - - - O O O - - - - - - - - -
- - - - O O O O O O O O - - - - -
- - - - - - O O O O O O O - - - -
- - - - - O O - - - O O O - - - -
- - - - O O O - - - O O O - - - -
- - - - O O O O - - O O O - - - -
- - - - - O O O O O O - - - - - -
- - - - - - - - - - - - - - - - -
Last edited on 27/03/2018