Doing things to glyphs ↩
- Move points by a random number of units
- Add anchor to selected glyphs
- Drawing inside a glyph with a pen
- Rasterizing a glyph
- Get glif path for glyph
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 ofglyph.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 ofglyph.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