Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add robofab examples #606

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions documentation/examples/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.. highlight:: python

fontParts examples
==================

FontParts is based on RoboFab. RoboFab had an extensive set of documentation and examples, which almost but not quite get you going in fontParts.

The examples of Robofab have been quick-and-dirty converted to be usable in fontParts. Where the code could not be made to work, the example has been deleted if it doesn't make sense outside of Robofab. Some other examples do not translate to fontParts in an obvious way, yet making them work would be worthwhile to people making the switch. These scripts have, possibly in a half converted state, been put in a directory called "helpneeded".

If you can assist, please fork the repo, fix one of more examples and create a pull request.

Many Robofab example scripts are intended to be run from inside a font editor. These have been converted to operate on a standalone font, called test.ufo. The scripts have been tested against DINish. Here's a quick start to get you going::

mkdir fontparts-playground; cd fontparts-playground
virtualenv ~/.venv/fontparts-playground
. ~/.venv/fontparts-playground/bin/activate
pip install fontParts
git clone [email protected]:playbeing/dinish.git
git clone [email protected]:robotools/fontParts.git
cd fontParts/documentation/examples/howtos
cp -pr ../../../../dinish/sources/Dinish/Dinish-Regular.ufo test.ufo
python otFeatures_00.py


12 changes: 12 additions & 0 deletions documentation/examples/howtos/buildingAccents_00.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# fontParts manual
# Buildingaccents howto
# usage examples

from fontParts.world import OpenFont

f = OpenFont("test.ufo")
f.newGlyph("aacute")
f["aacute"].appendComponent("a")
f["aacute"].appendComponent("acute", (200, 0))
f["aacute"].width = f["a"].width
f.update()
32 changes: 32 additions & 0 deletions documentation/examples/howtos/helpneeded/buildingAccents_01.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# fontParts manual
# Buildingaccents howto
# AccentBuilder examples

from fontParts.world import OpenFont
from fontParts.accentBuilder import AccentTools, buildRelatedAccentList

font = OpenFont("test.ufo")

# a list of accented glyphs that you want to build
myList = ['Aacute', 'aacute']

# search for glyphs related to glyphs in myList and add them to myList
myList = buildRelatedAccentList(font, myList)+myList

# start the class
at = AccentTools(font, myList)

# clear away any anchors that exist (this is optional)
at.clearAnchors()

# add necessary anchors if you want to
at.buildAnchors(ucXOffset=20, ucYOffset=40, lcXOffset=15, lcYOffset=30)

# print a report of any errors that occured
at.printAnchorErrors()

# build the accented glyphs if you want to
at.buildAccents()

# print a report of any errors that occured
at.printAccentErrors()
56 changes: 56 additions & 0 deletions documentation/examples/howtos/helpneeded/buildingAccents_02.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# fontParts manual
# Buildingaccents howto
# attribute examples

# a script to generate all necessary accented characters.
# this assumes all anchor points are set correctly.
# including doublelayer accents. so, add anchorpoints
# on the accents too!
# (c) evb

from fontParts.world import OpenFont
from fontParts.tools.toolsAll import readGlyphConstructions

f = OpenFont("test.ufo")

import string

theList = [
# caps
'AEacute',
'AEmacron',
'Aacute',
'Abreve',
# add all the accents you want in this list
]

con = readGlyphConstructions()
theList.sort()

def accentify(f, preflight=False):
print('start accentification', f.info.fullName)
slots = list(con.keys())
slots.sort()
for k in theList:
if k[-3:] in [".sc"]:
isSpecial = True
tag = k[-3:]
name = k[:-3]
else:
isSpecial = False
tag = ""
name = k
parts = con.get(name, None)
if parts is None:
print(k, "not defined?")
continue
base = parts[0]
accents = parts[1:]
f.generateGlyph(k, preflight=preflight)
f[k].mark = 100 + randint(-20, 20)
f[k].autoUnicodes()
f[k].update()
f.update()

accentify(f)
print('done')
14 changes: 14 additions & 0 deletions documentation/examples/howtos/helpneeded/generatingFonts_00.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# fontParts manual
# Generatefonts howto
# usage examples

import os.path
from fontParts.world import OpenFont

font = OpenFont("test.ufo")
path = font.path
dir, fileName = os.path.split(path)
# fontParts does not seem to expose the fullName attribute through the RInfo class
path = os.sep.join([dir, font.info.fullName])
# raises NotImplemented
font.generate('mactype1', path)
21 changes: 21 additions & 0 deletions documentation/examples/howtos/helpneeded/glifNames_00.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# fontParts manual
# Glifnames howto
# glyphNameToShortFileName examples

# examples of glyphname to glif name transformations
from fontParts.tools.glyphNameSchemes import glyphNameToShortFileName

# a short name
print(glyphNameToShortFileName("accent", None))

# a short name, starting with capital letter
print(glyphNameToShortFileName("Accent", None))

# a really long name - note the hexadecimal hash at the end
print(glyphNameToShortFileName("this_is_a_very_long_glyph_name.altswash2", None))

# a name with a period in it, 1
print(glyphNameToShortFileName("a.alt", None))

# a name with a period in it, 2
print(glyphNameToShortFileName(".notdef", None))
28 changes: 28 additions & 0 deletions documentation/examples/howtos/helpneeded/glyphMath_00.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# fontParts manual
# Glyphmath howto
# Fun examples

#FLM: Fun with GlyphMath

# this example is meant to run with the RoboFab Demo Font
# as the Current Font. So, if you're doing this in FontLab
# import the Demo Font UFO first.

from fontParts.world import OpenFont
from random import random

f = OpenFont("test.ufo")
condensedLight = f["a#condensed_light"]
wideLight = f["a#wide_light"]
wideBold = f["a#wide_bold"]

diff = wideLight - condensedLight

destination = f.newGlyph("a#deltaexperiment")
destination.clear()
x = wideBold + (condensedLight-wideLight)*random()

destination.appendGlyph( x)
destination.width = x.width

f.update()
6 changes: 6 additions & 0 deletions documentation/examples/howtos/helpneeded/interpolate_01.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from fontParts.world import OpenFont
f = OpenFont("test.ufo")
a = f["a"]
# fontParts RGlyph.isCompatible doesn't take the boolean argument.
# Moved to helpneeded as this argument is the only difference with interpolate_00.py
print(a.isCompatible(f["b"], True))
18 changes: 18 additions & 0 deletions documentation/examples/howtos/helpneeded/interpolate_02.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# fontParts manual
# Interpolate howto
# Straight Interpolating examples

from fontParts.world import OpenFont
minFont = OpenFont(pathToMinFont)
maxFont = OpenFont(pathToMaxFont)
# or any other way you like to get two font objects

inbetweenFont = OpenFont(pathToInbetweenFont)
# so now we have 3 font objects, right?

inbetweenFont.interpolate(.5, minFont, maxFont)
# presto, inbetweenFont is now 50% of one and 50% of the other

inbetweenFont.interpolate((.92, .12), minFont, maxFont)
# presto, inbetweenFont is now horizontally
# vertically interpolated in different ways.
12 changes: 12 additions & 0 deletions documentation/examples/howtos/helpneeded/kerning_00.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# fontParts doesn't seem to expose the kerning table.

# showing where the data lives in the RoboFab objects.
from fontParts.world import OpenFont

f = OpenFont("test.ufo")

# these are pairs
print(list(f.kerning.keys()))

# get the value for this pair
print(f.kerning[('MMK_L_baseserif', 'n')])
11 changes: 11 additions & 0 deletions documentation/examples/howtos/helpneeded/makeUFO_00.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# fontParts manual
# Makeufo howto
# Makeufo from a font binary examples

from fontParts.tools.toolsAll import fontToUFO
from fontParts.interface.all.dialogs import GetFile, PutFile

srcPath = GetFile('Select the source')
dstPath = PutFile('Save as...')

fontToUFO(srcPath, dstPath)
25 changes: 25 additions & 0 deletions documentation/examples/howtos/helpneeded/pens_00.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# fontParts manual
# Usepens howto
# usage examples

from fontParts.world import OpenFont

f = OpenFont("test.ufo")

newGlyph = f.newGlyph('demoDrawGlyph', clear=True)
newGlyph.width = 1000

# hey, what's this:
pen = newGlyph.getPen()
# ha! a sneaky way to get a pen object!

pen.moveTo((100, 100))
pen.lineTo((800, 100))
pen.curveTo((1000, 300), (1000, 600), (800, 800))
pen.lineTo((100, 800))
pen.lineTo((100, 100))
pen.closePath()

newGlyph.update()

f.update()
13 changes: 13 additions & 0 deletions documentation/examples/howtos/helpneeded/pens_01.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# fontParts manual
# Usepens howto
# attribute examples

from fontParts.world import OpenFont
from fontParts.pens.digestPen import DigestPointPen

f = OpenFont("test.ufo")

myPen = DigestPointPen()
f['period'].drawPoints(myPen)

print(myPen.getDigest())
13 changes: 13 additions & 0 deletions documentation/examples/howtos/helpneeded/pens_02.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# fontParts manual
# Usepens howto
# DigestPointStructurePen examples

from fontParts.world import OpenFont
from fontParts.pens.digestPen import DigestPointStructurePen

f = OpenFont("test.ufo")

myPen = DigestPointStructurePen()
f['period'].drawPoints(myPen)

print(myPen.getDigest())
7 changes: 7 additions & 0 deletions documentation/examples/howtos/helpneeded/pens_03.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from fontParts.world import OpenFont
from fontParts.pens.filterPen import flattenGlyph

f = OpenFont("test.ufo")
g = f["aacute"]
d = 10
flattenGlyph(g, d)
4 changes: 4 additions & 0 deletions documentation/examples/howtos/helpneeded/pens_04.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from fontParts.world import CurrentGlyph
from fontParts.pens.filterPen import thresholdGlyph
d = 10
thresholdGlyph(CurrentGlyph(), d)
5 changes: 5 additions & 0 deletions documentation/examples/howtos/helpneeded/pens_05.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from fontParts.world import CurrentGlyph
from fontParts.pens.filterPen import spikeGlyph
segmentLength = 20
spikeLength = 100
spikeGlyph(CurrentGlyph(), segmentLength, spikeLength)
3 changes: 3 additions & 0 deletions documentation/examples/howtos/helpneeded/pens_06.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from fontParts.world import CurrentGlyph
from fontParts.pens.filterPen import halftoneGlyph
halftoneGlyph(CurrentGlyph())
6 changes: 6 additions & 0 deletions documentation/examples/howtos/interpolate_00.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from fontParts.world import OpenFont
f = OpenFont("test.ufo")
a = f["a"]
# RGlyph.isCompatible doesn't accept the boolean argument.
#print(a.isCompatible(f["b"], False))
print(a.isCompatible(f["b"]))
6 changes: 6 additions & 0 deletions documentation/examples/howtos/lowLevel_00.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from fontParts.world import OpenFont
f = OpenFont("test.ufo")
# this is the high level RoboFab object
print(f)
# this is the low level FontLab object, not a part of RoboFab
print(f.naked())
11 changes: 11 additions & 0 deletions documentation/examples/howtos/otFeatures_00.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Getting to feature data in a UFO.

from fontParts.world import OpenFont

path = "test.ufo"

f = OpenFont(path)

print(list(f.lib.keys()))
print(f.lib["public.openTypeMeta"])
print(f.features.text)
8 changes: 8 additions & 0 deletions documentation/examples/howtos/otFeatures_01.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Getting to feature data in fontParts
from fontParts.world import OpenFont

f = OpenFont("test.ufo")

print(f.naked().features)

# these are raw fontParts feature objects.
4 changes: 4 additions & 0 deletions documentation/examples/howtos/scripting_00.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from fontParts.world import OpenFont
f = OpenFont("test.ufo")
# hey look! an open font dialog!
print(f)
5 changes: 5 additions & 0 deletions documentation/examples/howtos/scripting_01.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from fontParts.world import OpenFont
path = "test.ufo"
f = OpenFont(path)
# hey look! it opens the file without asking..
print(f)
4 changes: 4 additions & 0 deletions documentation/examples/howtos/scripting_02.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# in Fontlab:
from fontParts.world import OpenFont
f = OpenFont("test.ufo")
print(f)
1 change: 1 addition & 0 deletions documentation/examples/howtos/test.ufo
18 changes: 18 additions & 0 deletions documentation/examples/howtos/transformations_00.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# fontParts manual
# Usetransformations howto
# usage examples

from fontTools.misc.transform import Identity
from fontParts.world import OpenFont
import math

m = Identity
print(m)

m = m.rotate(math.radians(20))
print(m)

f = OpenFont("test.ufo")
for c in f:
c.transform(m)
c.update()
Loading