diff --git a/documentation/examples/README.rst b/documentation/examples/README.rst new file mode 100644 index 00000000..68f5b47e --- /dev/null +++ b/documentation/examples/README.rst @@ -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 git@github.com:playbeing/dinish.git + git clone git@github.com:robotools/fontParts.git + cd fontParts/documentation/examples/howtos + cp -pr ../../../../dinish/sources/Dinish/Dinish-Regular.ufo test.ufo + python otFeatures_00.py + + diff --git a/documentation/examples/howtos/buildingAccents_00.py b/documentation/examples/howtos/buildingAccents_00.py new file mode 100644 index 00000000..dfc9da5e --- /dev/null +++ b/documentation/examples/howtos/buildingAccents_00.py @@ -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() diff --git a/documentation/examples/howtos/helpneeded/buildingAccents_01.py b/documentation/examples/howtos/helpneeded/buildingAccents_01.py new file mode 100644 index 00000000..7d240949 --- /dev/null +++ b/documentation/examples/howtos/helpneeded/buildingAccents_01.py @@ -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() diff --git a/documentation/examples/howtos/helpneeded/buildingAccents_02.py b/documentation/examples/howtos/helpneeded/buildingAccents_02.py new file mode 100644 index 00000000..223a894a --- /dev/null +++ b/documentation/examples/howtos/helpneeded/buildingAccents_02.py @@ -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') diff --git a/documentation/examples/howtos/helpneeded/generatingFonts_00.py b/documentation/examples/howtos/helpneeded/generatingFonts_00.py new file mode 100644 index 00000000..22b93fcb --- /dev/null +++ b/documentation/examples/howtos/helpneeded/generatingFonts_00.py @@ -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) diff --git a/documentation/examples/howtos/helpneeded/glifNames_00.py b/documentation/examples/howtos/helpneeded/glifNames_00.py new file mode 100644 index 00000000..4021f68d --- /dev/null +++ b/documentation/examples/howtos/helpneeded/glifNames_00.py @@ -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)) diff --git a/documentation/examples/howtos/helpneeded/glyphMath_00.py b/documentation/examples/howtos/helpneeded/glyphMath_00.py new file mode 100644 index 00000000..fb23b777 --- /dev/null +++ b/documentation/examples/howtos/helpneeded/glyphMath_00.py @@ -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() diff --git a/documentation/examples/howtos/helpneeded/interpolate_01.py b/documentation/examples/howtos/helpneeded/interpolate_01.py new file mode 100644 index 00000000..dded3e25 --- /dev/null +++ b/documentation/examples/howtos/helpneeded/interpolate_01.py @@ -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)) diff --git a/documentation/examples/howtos/helpneeded/interpolate_02.py b/documentation/examples/howtos/helpneeded/interpolate_02.py new file mode 100644 index 00000000..bc456bb5 --- /dev/null +++ b/documentation/examples/howtos/helpneeded/interpolate_02.py @@ -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. diff --git a/documentation/examples/howtos/helpneeded/kerning_00.py b/documentation/examples/howtos/helpneeded/kerning_00.py new file mode 100644 index 00000000..c5f53c4d --- /dev/null +++ b/documentation/examples/howtos/helpneeded/kerning_00.py @@ -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')]) diff --git a/documentation/examples/howtos/helpneeded/makeUFO_00.py b/documentation/examples/howtos/helpneeded/makeUFO_00.py new file mode 100644 index 00000000..9d595c27 --- /dev/null +++ b/documentation/examples/howtos/helpneeded/makeUFO_00.py @@ -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) diff --git a/documentation/examples/howtos/helpneeded/pens_00.py b/documentation/examples/howtos/helpneeded/pens_00.py new file mode 100644 index 00000000..d1451ed1 --- /dev/null +++ b/documentation/examples/howtos/helpneeded/pens_00.py @@ -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() diff --git a/documentation/examples/howtos/helpneeded/pens_01.py b/documentation/examples/howtos/helpneeded/pens_01.py new file mode 100644 index 00000000..85f84c21 --- /dev/null +++ b/documentation/examples/howtos/helpneeded/pens_01.py @@ -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()) diff --git a/documentation/examples/howtos/helpneeded/pens_02.py b/documentation/examples/howtos/helpneeded/pens_02.py new file mode 100644 index 00000000..1821156c --- /dev/null +++ b/documentation/examples/howtos/helpneeded/pens_02.py @@ -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()) diff --git a/documentation/examples/howtos/helpneeded/pens_03.py b/documentation/examples/howtos/helpneeded/pens_03.py new file mode 100644 index 00000000..8eb1df30 --- /dev/null +++ b/documentation/examples/howtos/helpneeded/pens_03.py @@ -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) diff --git a/documentation/examples/howtos/helpneeded/pens_04.py b/documentation/examples/howtos/helpneeded/pens_04.py new file mode 100644 index 00000000..2f231f3a --- /dev/null +++ b/documentation/examples/howtos/helpneeded/pens_04.py @@ -0,0 +1,4 @@ +from fontParts.world import CurrentGlyph +from fontParts.pens.filterPen import thresholdGlyph +d = 10 +thresholdGlyph(CurrentGlyph(), d) diff --git a/documentation/examples/howtos/helpneeded/pens_05.py b/documentation/examples/howtos/helpneeded/pens_05.py new file mode 100644 index 00000000..7ff14ab6 --- /dev/null +++ b/documentation/examples/howtos/helpneeded/pens_05.py @@ -0,0 +1,5 @@ +from fontParts.world import CurrentGlyph +from fontParts.pens.filterPen import spikeGlyph +segmentLength = 20 +spikeLength = 100 +spikeGlyph(CurrentGlyph(), segmentLength, spikeLength) diff --git a/documentation/examples/howtos/helpneeded/pens_06.py b/documentation/examples/howtos/helpneeded/pens_06.py new file mode 100644 index 00000000..0369acd7 --- /dev/null +++ b/documentation/examples/howtos/helpneeded/pens_06.py @@ -0,0 +1,3 @@ +from fontParts.world import CurrentGlyph +from fontParts.pens.filterPen import halftoneGlyph +halftoneGlyph(CurrentGlyph()) diff --git a/documentation/examples/howtos/interpolate_00.py b/documentation/examples/howtos/interpolate_00.py new file mode 100644 index 00000000..07c6b8e3 --- /dev/null +++ b/documentation/examples/howtos/interpolate_00.py @@ -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"])) diff --git a/documentation/examples/howtos/lowLevel_00.py b/documentation/examples/howtos/lowLevel_00.py new file mode 100644 index 00000000..c8617b37 --- /dev/null +++ b/documentation/examples/howtos/lowLevel_00.py @@ -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()) diff --git a/documentation/examples/howtos/otFeatures_00.py b/documentation/examples/howtos/otFeatures_00.py new file mode 100644 index 00000000..219f609b --- /dev/null +++ b/documentation/examples/howtos/otFeatures_00.py @@ -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) diff --git a/documentation/examples/howtos/otFeatures_01.py b/documentation/examples/howtos/otFeatures_01.py new file mode 100644 index 00000000..65064c07 --- /dev/null +++ b/documentation/examples/howtos/otFeatures_01.py @@ -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. diff --git a/documentation/examples/howtos/scripting_00.py b/documentation/examples/howtos/scripting_00.py new file mode 100644 index 00000000..9d69f9ab --- /dev/null +++ b/documentation/examples/howtos/scripting_00.py @@ -0,0 +1,4 @@ +from fontParts.world import OpenFont +f = OpenFont("test.ufo") +# hey look! an open font dialog! +print(f) diff --git a/documentation/examples/howtos/scripting_01.py b/documentation/examples/howtos/scripting_01.py new file mode 100644 index 00000000..b05e4704 --- /dev/null +++ b/documentation/examples/howtos/scripting_01.py @@ -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) diff --git a/documentation/examples/howtos/scripting_02.py b/documentation/examples/howtos/scripting_02.py new file mode 100644 index 00000000..e29e7223 --- /dev/null +++ b/documentation/examples/howtos/scripting_02.py @@ -0,0 +1,4 @@ +# in Fontlab: +from fontParts.world import OpenFont +f = OpenFont("test.ufo") +print(f) diff --git a/documentation/examples/howtos/test.ufo b/documentation/examples/howtos/test.ufo new file mode 120000 index 00000000..816b1c0e --- /dev/null +++ b/documentation/examples/howtos/test.ufo @@ -0,0 +1 @@ +../test.ufo \ No newline at end of file diff --git a/documentation/examples/howtos/transformations_00.py b/documentation/examples/howtos/transformations_00.py new file mode 100644 index 00000000..ccf361cf --- /dev/null +++ b/documentation/examples/howtos/transformations_00.py @@ -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() diff --git a/documentation/examples/howtos/understandingContours_00.py b/documentation/examples/howtos/understandingContours_00.py new file mode 100644 index 00000000..9f97808d --- /dev/null +++ b/documentation/examples/howtos/understandingContours_00.py @@ -0,0 +1,7 @@ +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +# take a glyph (one with outlines obviously) +g = f["a"] +# get to contours by index: +print(g[0]) diff --git a/documentation/examples/howtos/understandingContours_02.py b/documentation/examples/howtos/understandingContours_02.py new file mode 100644 index 00000000..21ce91b4 --- /dev/null +++ b/documentation/examples/howtos/understandingContours_02.py @@ -0,0 +1,8 @@ +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +# get straight to the points in a contour +# through the points attribute +g = f["a"] +for aPt in g[0].points: + print(aPt) diff --git a/documentation/examples/howtos/understandingContours_03.py b/documentation/examples/howtos/understandingContours_03.py new file mode 100644 index 00000000..325167a4 --- /dev/null +++ b/documentation/examples/howtos/understandingContours_03.py @@ -0,0 +1,10 @@ +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +# bpoints +c = f["a"] +for aPt in c[0].bPoints: + print(aPt.anchor) + print(aPt.bcpIn) + print(aPt.bcpOut) + print(aPt.type) diff --git a/documentation/examples/objects/RAnchor_00.py b/documentation/examples/objects/RAnchor_00.py new file mode 100644 index 00000000..07632f06 --- /dev/null +++ b/documentation/examples/objects/RAnchor_00.py @@ -0,0 +1,11 @@ +# fontParts manual +# Anchor object +# usage examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") + +for g in f: + if len(g.anchors) > 0: + print(g, g.anchors) diff --git a/documentation/examples/objects/RAnchor_01.py b/documentation/examples/objects/RAnchor_01.py new file mode 100644 index 00000000..54f6249b --- /dev/null +++ b/documentation/examples/objects/RAnchor_01.py @@ -0,0 +1,12 @@ +# fontParts manual +# Anchor object +# attribute examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +g = f['a'] + +if len(g.anchors) > 0: + for a in g.anchors: + print(a.position) diff --git a/documentation/examples/objects/RComponent_00.py b/documentation/examples/objects/RComponent_00.py new file mode 100644 index 00000000..61a89489 --- /dev/null +++ b/documentation/examples/objects/RComponent_00.py @@ -0,0 +1,10 @@ +# the easiest way to get to a component +# is to get one from a glyph + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +g = f['gbreve'] + +for c in g.components: + print(c) diff --git a/documentation/examples/objects/RComponent_01.py b/documentation/examples/objects/RComponent_01.py new file mode 100644 index 00000000..f7220a30 --- /dev/null +++ b/documentation/examples/objects/RComponent_01.py @@ -0,0 +1,16 @@ +# fontParts manual +# Component object +# attribute examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") + +print(f['gbreve'].components[0].baseGlyph) +print(f['gbreve'].components[1].baseGlyph) + +# move the component in the base glyph +f['gbreve'].components[1].offset = (100,100) + +# scale the component in the base glyph +f['gbreve'].components[0].scale = (.5, .25) diff --git a/documentation/examples/objects/RContour_00.py b/documentation/examples/objects/RContour_00.py new file mode 100644 index 00000000..3a1fbfec --- /dev/null +++ b/documentation/examples/objects/RContour_00.py @@ -0,0 +1,15 @@ +# fontParts manual +# Contour object +# usage examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +# take a glyph (one with outlines obviously) +g = f['adieresis'] + +# get to contours by index: +print(g[0]) + +# Show that we can get straight to the bPoints +print(len(g[0].points)) diff --git a/documentation/examples/objects/RFont_00.py b/documentation/examples/objects/RFont_00.py new file mode 100644 index 00000000..2040a3aa --- /dev/null +++ b/documentation/examples/objects/RFont_00.py @@ -0,0 +1,15 @@ +# fontParts manual +# Font object +# Usage examples + +# start using the current font +from fontParts.world import OpenFont +f = OpenFont("test.ufo") + +# get a clean, empty new font object, +# appropriate for the current environment +from fontParts.world import RFont +f = RFont() + +# get an open dialog and start a new font +f = OpenFont("test.ufo") diff --git a/documentation/examples/objects/RFont_01.py b/documentation/examples/objects/RFont_01.py new file mode 100644 index 00000000..6e3941ab --- /dev/null +++ b/documentation/examples/objects/RFont_01.py @@ -0,0 +1,9 @@ +# fontParts manual +# Font object +# Iterate through the font object to get to the glyphs. + +from fontParts.world import OpenFont +f = OpenFont("test.ufo") + +for glyph in f: + print(glyph.name) diff --git a/documentation/examples/objects/RFont_02.py b/documentation/examples/objects/RFont_02.py new file mode 100644 index 00000000..f37379a9 --- /dev/null +++ b/documentation/examples/objects/RFont_02.py @@ -0,0 +1,8 @@ +# cache the kerning object for speed + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") + +cachedKerning = f.kerning +# continue to use cachedKerning, not f.kerning. \ No newline at end of file diff --git a/documentation/examples/objects/RFont_03.py b/documentation/examples/objects/RFont_03.py new file mode 100644 index 00000000..8155ffcc --- /dev/null +++ b/documentation/examples/objects/RFont_03.py @@ -0,0 +1,18 @@ +# fontParts manual +# Font object +# attribute examples +# Most useful attributes of RFont +# are actually stored in RFont.info + +from fontParts.world import OpenFont +f = OpenFont("test.ufo") +print(f.info.unitsPerEm) + +# kerning data is available in the kerning object: +print(f.kerning) + +# len() gives you the "length" of the font, i.e. the number of glyphs +print("glyphs in this font:", len(f)) + +# treat a font object as a dictionary to get to the glyphs +print(f["A"]) diff --git a/documentation/examples/objects/RFont_04.py b/documentation/examples/objects/RFont_04.py new file mode 100644 index 00000000..d02d7066 --- /dev/null +++ b/documentation/examples/objects/RFont_04.py @@ -0,0 +1,13 @@ +# fontParts manual +# Font object +# method examples + +from fontParts.world import OpenFont +f = OpenFont("test.ufo") + +# the keys() method returns a list of glyphnames: +print(list(f.keys())) + +# Not implemented in fontParts +# find unicodes for each glyph by using the postscript name: +#f.autoUnicodes() diff --git a/documentation/examples/objects/RFont_05.py b/documentation/examples/objects/RFont_05.py new file mode 100644 index 00000000..931f2f9f --- /dev/null +++ b/documentation/examples/objects/RFont_05.py @@ -0,0 +1,13 @@ +# fontParts manual +# Font object +# method examples, available in FontLab + +from fontParts.world import OpenFont +f = OpenFont("test.ufo") + +# the keys() method returns a list of glyphnames: +print(f.keys()) + +# Not implemented in fontParts +# generate font binaries +# f.generate('otfcff') diff --git a/documentation/examples/objects/RGlyph_00.py b/documentation/examples/objects/RGlyph_00.py new file mode 100644 index 00000000..f5a7d259 --- /dev/null +++ b/documentation/examples/objects/RGlyph_00.py @@ -0,0 +1,15 @@ +# fontParts manual +# Glyph object +# Usage examples + +# start using the current font +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +g = f['a'] + +# suppose you've done the right imports +# different ways of creating glyphs +# a new empty glyph object +from fontParts.world import RGlyph +g = RGlyph() diff --git a/documentation/examples/objects/RGlyph_01.py b/documentation/examples/objects/RGlyph_01.py new file mode 100644 index 00000000..ff95c926 --- /dev/null +++ b/documentation/examples/objects/RGlyph_01.py @@ -0,0 +1,28 @@ +# fontParts manual +# Glyph object +# attribute examples + +from fontParts.world import OpenFont, CurrentGlyph +f = OpenFont("test.ufo") + +# create a glyph object by asking the font +g = f["Adieresis"] + +# alternatively, create a glyph object for the current glyph +#g = CurrentGlyph() + +# get the width +print(g.width) + +# get the name +print(g.name) + +# a list of unicode values for this glyph. Can be more than 1! +print(g.unicodes) + +# set the width +g.width = 1000 +print(g.width) + +# get the number of contours in a glyph by getting its length +print(len(g)) diff --git a/documentation/examples/objects/RGlyph_02.py b/documentation/examples/objects/RGlyph_02.py new file mode 100644 index 00000000..62d06336 --- /dev/null +++ b/documentation/examples/objects/RGlyph_02.py @@ -0,0 +1,14 @@ +# fontParts manual +# Glyph object +# method examples + +from fontParts.world import OpenFont + +# get a glyph object from a font +f = OpenFont("test.ufo") +g = f["A"] +print(g) + +# move the glyph 10 units to the right, and 200 units up: +g = f["a"] +g.move((10, 200)) diff --git a/documentation/examples/objects/RGlyph_03.py b/documentation/examples/objects/RGlyph_03.py new file mode 100644 index 00000000..0936d063 --- /dev/null +++ b/documentation/examples/objects/RGlyph_03.py @@ -0,0 +1,21 @@ +# fontParts manual +# Glyph object +# method examples + +# In FontLab the baseglyph of a component can't be changed easily. +# This assumes that there will only be +# one component that needs to be remapped. + +def remapComponent(glyph, oldBaseGlyph, newBaseGlyph): + foundComponent = None + for component in glyph.components: + if component.baseGlyph == oldBaseGlyph: + foundComponent = component + break + if foundComponent is None: + return + offset = foundComponent.offset + scale = foundComponent.scale + glyph.removeComponent(component) + glyph.appendComponent(newBaseGlyph, offset=offset, scale=scale) + diff --git a/documentation/examples/objects/RInfo_00.py b/documentation/examples/objects/RInfo_00.py new file mode 100644 index 00000000..da97f671 --- /dev/null +++ b/documentation/examples/objects/RInfo_00.py @@ -0,0 +1,21 @@ +# fontParts manual +# Info object +# usage examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +print(f.info.postscriptFullName) +print(f.info.openTypeNameDesigner) + +f.info.openTypeNameDesigner = "Jan van Krimpen" +print(f.info.openTypeNameDesigner) +print(f.info.openTypeOS2VendorID) +print(f.info.unitsPerEm) +print(f.info.xHeight) +print(f.info.openTypeNameLicenseURL) + +# but you can set the values as well +f.info.postscriptUniqueID = 4309359 +f.info.openTypeNameDesigner = "Eric Gill" + diff --git a/documentation/examples/objects/RLib_00.py b/documentation/examples/objects/RLib_00.py new file mode 100644 index 00000000..6bd08854 --- /dev/null +++ b/documentation/examples/objects/RLib_00.py @@ -0,0 +1,13 @@ +# fontParts manual +# Lib object +# attribute examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") + +# RFont objects have a lib: +print(f.lib) + +# content of the lib of a font exported from RoboFog +print(list(f.lib.keys())) diff --git a/documentation/examples/objects/RPoint_00.py b/documentation/examples/objects/RPoint_00.py new file mode 100644 index 00000000..bcdde6cb --- /dev/null +++ b/documentation/examples/objects/RPoint_00.py @@ -0,0 +1,18 @@ +# fontParts manual +# Point object +# usage examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +g = f['a'] + +contour = g[0] +print(contour.points[0]) + +from random import randint +for p in contour.points: + p.x += randint(-10,10) + p.y += randint(-10,10) + +contour.update() diff --git a/documentation/examples/objects/RSegment_00.py b/documentation/examples/objects/RSegment_00.py new file mode 100644 index 00000000..3847ec81 --- /dev/null +++ b/documentation/examples/objects/RSegment_00.py @@ -0,0 +1,12 @@ +# fontParts manual +# Segment object +# usage examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") + +for g in f: + for contour in g: + for segment in contour: + print(segment) diff --git a/documentation/examples/objects/RSegment_01.py b/documentation/examples/objects/RSegment_01.py new file mode 100644 index 00000000..cfb814e6 --- /dev/null +++ b/documentation/examples/objects/RSegment_01.py @@ -0,0 +1,17 @@ +# fontParts manual +# Segment object +# attribute examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") + +for g in f: + for contour in g: + for segment in contour: + print(len(segment)) + print(segment.type) + print(segment.smooth) + print(segment.points) + print(segment.onCurve) + print(segment.offCurve) diff --git a/documentation/examples/objects/RSegment_02.py b/documentation/examples/objects/RSegment_02.py new file mode 100644 index 00000000..679a4b98 --- /dev/null +++ b/documentation/examples/objects/RSegment_02.py @@ -0,0 +1,12 @@ +# fontParts manual +# Segment object +# method examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") + +for g in f: + for contour in g: + for segment in contour: + segment.move((50, 25)) diff --git a/documentation/examples/objects/bPoint_00.py b/documentation/examples/objects/bPoint_00.py new file mode 100644 index 00000000..2e4b9e29 --- /dev/null +++ b/documentation/examples/objects/bPoint_00.py @@ -0,0 +1,10 @@ +# fontParts manual +# bPoint object +# Usage examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +g = f['a'] +for aPt in g[0].bPoints: + print(aPt) diff --git a/documentation/examples/objects/bPoint_01.py b/documentation/examples/objects/bPoint_01.py new file mode 100644 index 00000000..6bb9a780 --- /dev/null +++ b/documentation/examples/objects/bPoint_01.py @@ -0,0 +1,11 @@ +# fontParts manual +# bPoint object +# Attribute examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +g = f['a'] + +for aPt in g[0].bPoints: + print(aPt.bcpIn, aPt.bcpOut, aPt.anchor) diff --git a/documentation/examples/objects/helpneeded/RKerning_00.py b/documentation/examples/objects/helpneeded/RKerning_00.py new file mode 100644 index 00000000..16dcd717 --- /dev/null +++ b/documentation/examples/objects/helpneeded/RKerning_00.py @@ -0,0 +1,17 @@ +# fontParts manual +# Kerning object +# usage examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +print(f.kerning) + +# f.kerning returns an empty dict in fontParts. That can't be right, +# so this example goes into helpneeded UFN. The test font does have +# kerning for the V,A kern pair through a kerning class. + +# getting a value from the kerning dictionary +print(f.kerning[('V', 'A')]) +print(f.kerning[('T', 'X')]) +print(list(f.kerning.keys())) diff --git a/documentation/examples/objects/helpneeded/psHints_01.py b/documentation/examples/objects/helpneeded/psHints_01.py new file mode 100644 index 00000000..93e915aa --- /dev/null +++ b/documentation/examples/objects/helpneeded/psHints_01.py @@ -0,0 +1,7 @@ +# example of accessing the hint data, +# using the font.psHints object. + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +print(f.psHints.asDict()) diff --git a/documentation/examples/objects/helpneeded/psHints_02.py b/documentation/examples/objects/helpneeded/psHints_02.py new file mode 100644 index 00000000..cc6bcfc7 --- /dev/null +++ b/documentation/examples/objects/helpneeded/psHints_02.py @@ -0,0 +1,18 @@ +# example of scaling the hint data. + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +print(f.psHints.asDict()) + +# a math operation returns a new, unbound object +ps2 = f.psHints * .5 + +# it needs to be rounded first +ps2.round() + +# now you can add the values to the FL object +f.psHints.update(ps2) + +# see those zones skip! +f.update() diff --git a/documentation/examples/objects/helpneeded/psHints_03.py b/documentation/examples/objects/helpneeded/psHints_03.py new file mode 100644 index 00000000..4ca8154b --- /dev/null +++ b/documentation/examples/objects/helpneeded/psHints_03.py @@ -0,0 +1,96 @@ +#FLM: Get and set font level PostScript hint data. + +from fontParts.world import OpenFont +""" +This script shows the way to get to the font level postscript hint values. +These values were available from the fl layer, but not in RoboFab. +Now they're available in RoboFab in a slightly easier to use format. +The values also export to UFO and import from UFO. + +Check the FontLab FontInfo panel / Hinting Settings + +""" +f = OpenFont("test.ufo") + +# the fontlevel postscript hint data is accessible through the psHints attribute + +print() +print("This script shows the attributes of psHints:", f.psHints) + +# now let's have a look at the values +# blueScale, blueShift, blueFuzz and forceBold are all single values. + +print("blueScale", f.psHints.blueScale) +f.psHints.blueScale = .5 +print("blueScale changed", f.psHints.blueScale) + +print("blueShift", f.psHints.blueShift) +f.psHints.blueShift = 5 +print("blueShift changed", f.psHints.blueShift) + +print("blueFuzz", f.psHints.blueFuzz) +f.psHints.blueFuzz = 0 +print("blueFuzz changed", f.psHints.blueFuzz) + +print("forceBold", f.psHints.forceBold) +f.psHints.forceBold = 1 +print("forceBold changed", f.psHints.forceBold) + +# the following values are represented as lists. +# Important Note: you can only set the whole list, not individual items. +# So get the list, make changes to it, then set the list +# Zones are represented as tuples of integers, so it's easier to +# see which values belong together. FL stores the values as +# a single list of numbers. + +# T1 spec says blueValues, FL says Primary Alignment Zones, under "Set Local Alignment Zones". +print("blueValues", f.psHints.blueValues) +# remove the last zone +f.psHints.blueValues = f.psHints.blueValues[:-1] +print("blueValues changed", f.psHints.blueValues) +# add a new zone +f.psHints.blueValues = f.psHints.blueValues + [(750, 770)] +print("blueValues changed", f.psHints.blueValues) + +# T1 spec says otherBlues, FL says Secondary Alignment Zones, under "Set Local Alignment Zones". +print("otherBlues", f.psHints.otherBlues) +# remove the last zone +f.psHints.otherBlues = f.psHints.otherBlues[:-1] +print("otherBlues changed", f.psHints.otherBlues) +# add a new zone +f.psHints.otherBlues = f.psHints.otherBlues + [(750, 770)] +print("otherBlues changed", f.psHints.otherBlues) + +# T1 spec says familyBlues, FL says Primary Alignment Zones, under "Set Family Alignment Zones". +print("familyBlues", f.psHints.familyBlues) +# remove the last zone +f.psHints.familyBlues = f.psHints.familyBlues[:-1] +print("familyBlues changed", f.psHints.familyBlues) +# add a new zone +f.psHints.familyBlues = f.psHints.familyBlues + [(750, 770)] +print("familyBlues changed", f.psHints.familyBlues) + +# T1 spec says familyOtherBlues, FL says Seconday Alignment Zones, under "Set Family Alignment Zones". +print("familyOtherBlues", f.psHints.familyOtherBlues) +# remove the last zone +f.psHints.familyOtherBlues = f.psHints.familyOtherBlues[:-1] +print("familyOtherBlues changed", f.psHints.familyOtherBlues) +# add a new zone +f.psHints.familyOtherBlues = f.psHints.familyOtherBlues + [(750, 770)] +print("familyOtherBlues changed", f.psHints.familyOtherBlues) + +# The horizontal stems are represented as a list of single values. +print("hStems", f.psHints.hStems) +f.psHints.hStems = f.psHints.hStems[:-1] +print("hStems changed", f.psHints.hStems) +# add a new stem +f.psHints.hStems = f.psHints.hStems + [100] +print("hStems changed", f.psHints.hStems) + +# The vertical stems are represented as a list of single values. +print("vStems", f.psHints.vStems) +f.psHints.vStems = f.psHints.vStems[:-1] +print("vStems changed", f.psHints.vStems) +# add a new stem +f.psHints.vStems = f.psHints.vStems + [100] +print("vStems changed", f.psHints.vStems) diff --git a/documentation/examples/objects/pen_00.py b/documentation/examples/objects/pen_00.py new file mode 100644 index 00000000..e8adc834 --- /dev/null +++ b/documentation/examples/objects/pen_00.py @@ -0,0 +1,12 @@ +# fontParts manual +# Pen object +# usage examples + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +g = f['a'] + +pen = g.getPen() + +# do stuff with the pen to draw in this glyph diff --git a/documentation/examples/objects/psHints_00.py b/documentation/examples/objects/psHints_00.py new file mode 100644 index 00000000..f69356b0 --- /dev/null +++ b/documentation/examples/objects/psHints_00.py @@ -0,0 +1,11 @@ +# example of accessing the postscript blues +# data using the font.info attributes. + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") + +print(f.info.postscriptBlueValues) +print(f.info.postscriptOtherBlues) +print(f.info.postscriptFamilyBlues) +print(f.info.postscriptFamilyOtherBlues) diff --git a/documentation/examples/talks/helpneeded/interpol_00.py b/documentation/examples/talks/helpneeded/interpol_00.py new file mode 100644 index 00000000..a006cece --- /dev/null +++ b/documentation/examples/talks/helpneeded/interpol_00.py @@ -0,0 +1,10 @@ +# robothon06 +# interpolate two glyphs in the same font + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +factor = 0.5 + +f["C"].interpolate(factor, f["A"], f["B"]) +f["C"].update() \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/interpol_01.py b/documentation/examples/talks/helpneeded/interpol_01.py new file mode 100644 index 00000000..2c055265 --- /dev/null +++ b/documentation/examples/talks/helpneeded/interpol_01.py @@ -0,0 +1,19 @@ +# robothon06 +# interpolate two glyphs in the same font a bunch of times + +from fontParts.world import OpenFont, RGlyph + +f = OpenFont("test.ufo") + +# This example runs to completion, but it doesn't do anything in fontParts. +# In robofab, it created a new glyph using the magic spring-into-existence +# syntax f[name].interpolate(...) on a non-existing f[name], which doesn't +# work in fontParts. But neither does this attempt to make it work. +for i in range(0, 10): + factor = i*.1 + name = "result_%f"%factor + print("interpolating", name) + f[name] = RGlyph() + f[name].interpolate(factor, f["A"], f["B"]) + +f.update() diff --git a/documentation/examples/talks/helpneeded/interpol_02.py b/documentation/examples/talks/helpneeded/interpol_02.py new file mode 100644 index 00000000..6b3c859f --- /dev/null +++ b/documentation/examples/talks/helpneeded/interpol_02.py @@ -0,0 +1,36 @@ +# robothon06 + +from fontParts.world import OpenFont + +# We need to import a class with a different +# implementation for the glyph object. +# It looks a bit odd, but this is how it is done +from fontParts.objects.objectsRF import RGlyph as _RGlyph + +f = OpenFont("test.ufo") + +# pick two compatible glyphs as masters +m1 = f["A"] +m2 = f["B"] + +# make a new glyph object from this other glyph class +g = _RGlyph() + +# interpolation factor which is bound to make floats +oddFactor = 0.2382345 + +# go! +g.interpolate(oddFactor, m1, m2) + +# let's have a look at the raw results +for contour in g: + for pt in contour.points: + print("float", pt.x, pt.y) + +# a glyph can round itself off: +g.round() + +# and then it looks like integers again +for contour in g: + for pt in contour.points: + print("integer", pt.x, pt.y) diff --git a/documentation/examples/talks/helpneeded/interpol_03.py b/documentation/examples/talks/helpneeded/interpol_03.py new file mode 100644 index 00000000..9750a91b --- /dev/null +++ b/documentation/examples/talks/helpneeded/interpol_03.py @@ -0,0 +1,5 @@ +# see if "A" and "B" can interpolate +from fontParts.world import OpenFont +f = OpenFont("test.ufo") +a = f["a"] +print(a.isCompatible(f["b"], False)) diff --git a/documentation/examples/talks/helpneeded/interpol_04.py b/documentation/examples/talks/helpneeded/interpol_04.py new file mode 100644 index 00000000..8d2c3aa0 --- /dev/null +++ b/documentation/examples/talks/helpneeded/interpol_04.py @@ -0,0 +1,6 @@ +# see if "A" and "B" can interpolate +# and find out what's wrong if you can +from fontParts.world import OpenFont +f = OpenFont("test.ufo") +a = f["a"] +print(a.isCompatible(f["b"], True)) diff --git a/documentation/examples/talks/helpneeded/interpol_05.py b/documentation/examples/talks/helpneeded/interpol_05.py new file mode 100644 index 00000000..2eb770f8 --- /dev/null +++ b/documentation/examples/talks/helpneeded/interpol_05.py @@ -0,0 +1,16 @@ +# robothon06 +# prepare glyph for interpolation +# move startpoints +# fix directions +# fix contour order + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +glyph = f["A"] + +glyph.autoContourOrder() +glyph.correctDirection() +for c in glyph.contours: + c.autoStartSegment() +glyph.update() diff --git a/documentation/examples/talks/helpneeded/interpol_06.py b/documentation/examples/talks/helpneeded/interpol_06.py new file mode 100644 index 00000000..8999991a --- /dev/null +++ b/documentation/examples/talks/helpneeded/interpol_06.py @@ -0,0 +1,22 @@ +# robothon06 +# interpolate two fonts + +from fontParts.world import SelectFont, NewFont +from fontParts.interface.all.dialogs import AskString + +font1 = SelectFont("Select font 1") +font2 = SelectFont("Select font 2") + +value = AskString("What percentage?") +value = int(value) * .01 + +destination = NewFont() + +# this interpolates the glyphs +destination.interpolate(value, font1, font2, doProgress=True) + +# this interpolates the kerning +# comment this line out of you're just testing +destination.kerning.interpolate(font1.kerning, font2.kerning, value) + +destination.update() \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/interpol_07.py b/documentation/examples/talks/helpneeded/interpol_07.py new file mode 100644 index 00000000..03419364 --- /dev/null +++ b/documentation/examples/talks/helpneeded/interpol_07.py @@ -0,0 +1,37 @@ +# glyphmath example, using glyphs in math +# in the test font: two interpolatable, different glyphs +# on positions A and B. + +from fontParts.world import OpenFont +f = OpenFont("test.ufo") + +# glyphmath +a = f["A"] +b = f["B"] + +# multiply works as scaling up +d = a * 2 +# or +d = 2 * a + +# note: as of robofab svn version 200, +# the "as" argument in insertGlyph has changed to "name" +f.insertGlyph(d, name="A.A_times_2") + +# division works as scaling down +d = a / 2 +f.insertGlyph(d, name="A.A_divide_2") + +# addition: add coordinates of each point +d = a + b +f.insertGlyph(d, name="A.A_plus_B") + +# subtraction: subtract coordinates of each point +d = a - b +f.insertGlyph(d, name="A.A_minus_B") + +# combination: interpolation! +d = a + .5 * (b-a) +f.insertGlyph(d, name="A.A_interpolate_B") + +f.update() \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/interpol_08.py b/documentation/examples/talks/helpneeded/interpol_08.py new file mode 100644 index 00000000..6b46093b --- /dev/null +++ b/documentation/examples/talks/helpneeded/interpol_08.py @@ -0,0 +1,38 @@ +# robothon06 +# interpolate two fonts with a series of factors. +# for each factor create a new font file. + +import os +from fontParts.world import SelectFont, NewFont +from fontParts.interface.all.dialogs import AskString, GetFolder + +font1 = SelectFont("Select font 1") +font2 = SelectFont("Select font 2") +where = GetFolder("Select a folder to save the interpolations") + +instances = [ + ("Light", 0), + ("NotTooLight", 0.25), + ("Regular", 0.5), + ("Demi", 0.75), + ("Medium", 1), +] + +for thing in instances: + name, value = thing + print("generating", name, value) + dst = NewFont() + # this interpolates the glyphs + dst.interpolate(value, font1, font2, doProgress=True) + # this interpolates the kerning + # comment this line out of you're just testing + #dst.kerning.interpolate(font1.kerning, font2.kerning, value) + dst.info.familyName = "MyBigFamily" + dst.info.styleName = name + dst.info.autoNaming() + dst.update() + fileName = dst.info.familyName + "-" + dst.info.styleName + ".vfb" + path = os.path.join(where, fileName) + print('saving at', path) + dst.save(path) + dst.close() diff --git a/documentation/examples/talks/helpneeded/interpol_09.py b/documentation/examples/talks/helpneeded/interpol_09.py new file mode 100644 index 00000000..bd0c620c --- /dev/null +++ b/documentation/examples/talks/helpneeded/interpol_09.py @@ -0,0 +1,25 @@ +# robothon06 +# Get started with a condensed if you have a regular and a bold: +# seperate x, y interpolation to make stems fatter +# then scaling to reduce width +# stems will get their original thickness + +from fontParts.world import OpenFont +f = OpenFont("test.ufo") + +# these are measurements you have to take +# from your font. The width of a stem. + +lightStem = 106 +fatStem = 200 + +for i in range(0, 10): + factor = (i * 0.1, 0) + name = "result_%f" % factor[0] + scale = float(lightStem) / (lightStem + factor[0] * (fatStem - lightStem)) + print(factor, scale) + f[name].interpolate(factor, f["A"], f["B"]) + f[name].scale((scale, 1)) + f[name].leftMargin = f["A"].leftMargin + f[name].rightMargin = f["A"].rightMargin +f.update() diff --git a/documentation/examples/talks/helpneeded/nonelab_00.py b/documentation/examples/talks/helpneeded/nonelab_00.py new file mode 100644 index 00000000..e6a370b9 --- /dev/null +++ b/documentation/examples/talks/helpneeded/nonelab_00.py @@ -0,0 +1,25 @@ +# robothon06 +# demo of executing python in FontLab, MacOS only + +# this script runs in the Python IDE +# it will send some python code to FontLab +# FontLab will execute the python code: +# it will find the current glyph and send it to our other script. + +from fontParts.tools.remote import runFontLabRemote, receiveGlyph +from fontParts.world import RFont + +# this is what we want FontLab to do: +pythonCode = """ +from fontParts.world import CurrentGlyph +from fontParts.tools.remote import transmitGlyph +g = CurrentGlyph() +transmitGlyph(g) +""" + +# this the font where we'll store the glyph from FontLab +destFont = RFont() + +result = runFontLabRemote(pythonCode) +receiveGlyph(result, destFont) +print(list(destFont.keys())) diff --git a/documentation/examples/talks/helpneeded/session1_00.py b/documentation/examples/talks/helpneeded/session1_00.py new file mode 100644 index 00000000..53134031 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session1_00.py @@ -0,0 +1,2 @@ +from fontParts.world import OpenFont +print(CurrentFont()) \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session1_01.py b/documentation/examples/talks/helpneeded/session1_01.py new file mode 100644 index 00000000..2718b1fe --- /dev/null +++ b/documentation/examples/talks/helpneeded/session1_01.py @@ -0,0 +1,3 @@ +# open a glyph in FL first! +from fontParts.world import CurrentGlyph +print(CurrentGlyph()) diff --git a/documentation/examples/talks/helpneeded/session1_02.py b/documentation/examples/talks/helpneeded/session1_02.py new file mode 100644 index 00000000..8d2050b2 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session1_02.py @@ -0,0 +1,3 @@ +# open a couple of fonts in FL first! +from fontParts.world import AllFonts +print(AllFonts()) diff --git a/documentation/examples/talks/helpneeded/session1_03.py b/documentation/examples/talks/helpneeded/session1_03.py new file mode 100644 index 00000000..e7c13977 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session1_03.py @@ -0,0 +1,7 @@ +# open a couple of fonts in FL first! +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") +print(font.path) +print(font.kerning) +print(font.info) \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session1_04.py b/documentation/examples/talks/helpneeded/session1_04.py new file mode 100644 index 00000000..be56ccb1 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session1_04.py @@ -0,0 +1,16 @@ +# robothon06 +# getting data from the info object + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") + +# naming attributes +print(font.info.familyName) +print(font.info.styleName) +print(font.info.fullName) + +# dimension attributes +print(font.info.unitsPerEm) +print(font.info.ascender) +print(font.info.descender) \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session1_05.py b/documentation/examples/talks/helpneeded/session1_05.py new file mode 100644 index 00000000..dfcc1c61 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session1_05.py @@ -0,0 +1,22 @@ +# robothon06 +# setting data in the info object + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") + +# naming attributes +font.info.familyName = "MyFamily" +print(font.info.familyName) +font.info.styleName = "Roman" +print(font.info.styleName) +font.info.fullName = font.info.familyName + '-' + font.info.styleName +print(font.info.fullName) + +# dimension attributes +font.info.ascender = 600 +print(font.info.ascender) +font.info.descender = -400 +print(font.info.descender) + +font.update() \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session1_06.py b/documentation/examples/talks/helpneeded/session1_06.py new file mode 100644 index 00000000..71527c84 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session1_06.py @@ -0,0 +1,14 @@ +# robothon06 +# get a particular glyph + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") + +font.info.familyName = "myFamilyName" +font.info.styleName = "myStyleName" +font.info.autoNaming() + +print(font.info.fullName) +print(font.info.fontName) +print(font.info.fondName) \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session1_07.py b/documentation/examples/talks/helpneeded/session1_07.py new file mode 100644 index 00000000..882d11ba --- /dev/null +++ b/documentation/examples/talks/helpneeded/session1_07.py @@ -0,0 +1,11 @@ +# robothon06 +# get a particular glyph + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") + +print(font['A']) +print(font['Adieresis']) +print(font['two']) +print(font['afii12934']) \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session1_08.py b/documentation/examples/talks/helpneeded/session1_08.py new file mode 100644 index 00000000..8e8d827d --- /dev/null +++ b/documentation/examples/talks/helpneeded/session1_08.py @@ -0,0 +1,11 @@ +# robothon06 +# iteration through glyphs in a font + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") + +print("font has %d glyphs" % len(font)) + +for glyph in font: + print(glyph) \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session1_09.py b/documentation/examples/talks/helpneeded/session1_09.py new file mode 100644 index 00000000..98b3c507 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session1_09.py @@ -0,0 +1,18 @@ +# iteration through alphabetically sorted glyphnames + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") +print("font has %d glyphs" % len(font)) + +# names is now a list of strings, the names of the glyphs +# not the glyphs themselves! +names = list(font.keys()) + +# the list of names is sorted +names.sort() + +# now we iterate through the list of names +for glyphName in names: + # now we ask for the glyph with glyphName + print(font[glyphName]) diff --git a/documentation/examples/talks/helpneeded/session2_00.py b/documentation/examples/talks/helpneeded/session2_00.py new file mode 100644 index 00000000..dbb12177 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session2_00.py @@ -0,0 +1,16 @@ +# robothon 2009 +# set basic attributes in a glyph + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") +glyph = font['A'] + +print(glyph.name) +print(glyph.width) +print(glyph.leftMargin) +print(glyph.rightMargin) +print(glyph.box) +print(glyph.str) + +glyph.update() \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session2_01.py b/documentation/examples/talks/helpneeded/session2_01.py new file mode 100644 index 00000000..d9390156 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session2_01.py @@ -0,0 +1,21 @@ +# robothon06 +# set basic attributes in a glyph + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") +glyph = font['A'] + +glyph.width = 200 +print(glyph.width) + +glyph.leftMargin = 50 +print(glyph.leftMargin) + +glyph.rightMargin = 50 +print(glyph.rightMargin) + +glyph.str = 666 +print(glyph.str) + +glyph.update() diff --git a/documentation/examples/talks/helpneeded/session2_02.py b/documentation/examples/talks/helpneeded/session2_02.py new file mode 100644 index 00000000..0575b8a3 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session2_02.py @@ -0,0 +1,18 @@ +# robothon06 +# use some methods to transform a glyph + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") + +# ask a font for a glyph by name +glyph = font['A'] + +# now you have a glyph object +# make it do stuff by calling some of its methods +glyph.move((100, 75)) +glyph.scale((.5, 1.5)) +glyph.appendGlyph(font['B']) +glyph.removeOverlap() +glyph.correctDirection() +glyph.update() diff --git a/documentation/examples/talks/helpneeded/session2_03.py b/documentation/examples/talks/helpneeded/session2_03.py new file mode 100644 index 00000000..be9409b6 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session2_03.py @@ -0,0 +1,9 @@ +# robothon06 +# iterate through a glyph's contours + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") + +glyph = font["A"] +print(glyph.getParent()) \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session2_04.py b/documentation/examples/talks/helpneeded/session2_04.py new file mode 100644 index 00000000..dd84b1a8 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session2_04.py @@ -0,0 +1,10 @@ +# robothon06 +# iterate through a glyph's contours + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") +glyph = font['A'] +print("glyph has %d contours" % len(glyph)) +for contour in glyph.contours: + print(contour) \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session2_05.py b/documentation/examples/talks/helpneeded/session2_05.py new file mode 100644 index 00000000..469a9685 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session2_05.py @@ -0,0 +1,12 @@ +# robothon06 +# get a specific contour and view it +# through point, segment and bPoint structures + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") +glyph = font['A'] +contour = glyph[0] +print(contour.points) +print(countours.segments) +print(contour.bPoints) diff --git a/documentation/examples/talks/helpneeded/session2_06.py b/documentation/examples/talks/helpneeded/session2_06.py new file mode 100644 index 00000000..aa413043 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session2_06.py @@ -0,0 +1,9 @@ +# robothon06 +# iterate through points + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") +glyph = font['A'] +for p in glyph[0].points: + print(p.x, p.y, p.type) \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session2_07.py b/documentation/examples/talks/helpneeded/session2_07.py new file mode 100644 index 00000000..35ab12e3 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session2_07.py @@ -0,0 +1,37 @@ +# robothon06 +# get a pen and draw something in the current glyph +# what will it draw? ha! run the script and find out! + +from fontParts.world import CurrentGlyph + +g = CurrentGlyph() +myPen = g.getPen() + +# myPen is a pen object of a type meant for +# constructing paths in a glyph. +# So rather than use this pen with the glyph's +# own draw() method, we're going to tell it +# to do things ourselves. (Just like DrawBot!) +print(myPen) + +myPen.moveTo((344, 645)) +myPen.lineTo((647, 261)) +myPen.lineTo((662, -32)) +myPen.lineTo((648, -61)) +myPen.lineTo((619, -61)) +myPen.lineTo((352, 54)) +myPen.lineTo((72, 446)) +myPen.lineTo((117, 590)) +myPen.lineTo((228, 665)) +myPen.closePath() +myPen.moveTo((99, 451)) +myPen.lineTo((365, 74)) +myPen.curveTo((359, 122), (376, 178), (420, 206)) +myPen.curveTo((422, 203), (142, 579), (142, 579)) +myPen.closePath() +myPen.moveTo((631, -32)) +myPen.lineTo((629, 103)) +myPen.curveTo((556, 111), (524, 71), (508, 20)) +myPen.closePath() + +g.update() \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session2_08.py b/documentation/examples/talks/helpneeded/session2_08.py new file mode 100644 index 00000000..95a8f7e9 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session2_08.py @@ -0,0 +1,15 @@ +# robothon06 +# get a pen and use it to print the coordinates +# to the output window. This is actually almost-python +# code which you can use it other scripts! + +from fontParts.world import OpenFont +from fontParts.pens.pointPen import PrintingSegmentPen + +font = OpenFont("test.ufo") +glyph = font['A'] + +# PrintingSegmentPen won't actually draw anything +# just print the coordinates to the output: +pen = PrintingSegmentPen() +glyph.draw(pen) diff --git a/documentation/examples/talks/helpneeded/session2_09.py b/documentation/examples/talks/helpneeded/session2_09.py new file mode 100644 index 00000000..a8dc1220 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session2_09.py @@ -0,0 +1,45 @@ +# robothon06 +# rasterise the shape in glyph "A" +# and draw boxes in a new glyph named "A.silly" + +from fontParts.world import OpenFont, CurrentGlyph + +sourceGlyph = "a" + +f = OpenFont("test.ufo") +source = f[sourceGlyph] + +# find out how big the shape is from the glyph.box attribute +xMin, yMin, xMax, yMax = source.box + +# create a new glyph +dest = f.newGlyph(sourceGlyph+".silly") +dest.width = source.width + +# get a pen to draw in the new glyph +myPen = dest.getPen() + +# a function which draws a rectangle at a specified place +def drawRect(pen, x, y, size=50): + pen.moveTo((x-.5*size, y-.5*size)) + pen.lineTo((x+.5*size, y-.5*size)) + pen.lineTo((x+.5*size, y+.5*size)) + pen.lineTo((x-.5*size, y+.5*size)) + pen.closePath() + +# the size of the raster unit +resolution = 30 + +# draw from top to bottom +yValues = list(range(yMin, yMax, resolution)) +yValues.reverse() + +# go for it! +for y in yValues: + for x in range(xMin, xMax, resolution): + # check the source glyph is white or black at x,y + if source.pointInside((x, y)): + drawRect(myPen, x, y, resolution-5) + # update for each line if you like the animation + # otherwise move the update() out of the loop + dest.update() diff --git a/documentation/examples/talks/helpneeded/session2_10.py b/documentation/examples/talks/helpneeded/session2_10.py new file mode 100644 index 00000000..7fe73f5c --- /dev/null +++ b/documentation/examples/talks/helpneeded/session2_10.py @@ -0,0 +1,10 @@ +# use a point pen + +from fontParts.world import OpenFont +from fontParts.pens.pointPen import PrintingPointPen + +font = OpenFont("test.ufo") +glyph = font['A'] + +pen = PrintingPointPen() +glyph.drawPoints(pen) diff --git a/documentation/examples/talks/helpneeded/session2_11.py b/documentation/examples/talks/helpneeded/session2_11.py new file mode 100644 index 00000000..891db802 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session2_11.py @@ -0,0 +1,15 @@ +# robothon06 +# Use FontLab pathfinder functionality to cut one glyph from another + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +base = f["A"] +cutter = f["B"] +dest = f["C"] + +dest.clear() +dest.appendGlyph(base) +dest.width = base.width +dest.naked().Bsubtract(cutter.naked()) +dest.update() diff --git a/documentation/examples/talks/helpneeded/session3_00.py b/documentation/examples/talks/helpneeded/session3_00.py new file mode 100644 index 00000000..fea785b3 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session3_00.py @@ -0,0 +1,12 @@ +# robothon06 +# work with kerning 1 +from fontParts.world import OpenFont +font = OpenFont("test.ufo") +# now the kerning object is generated once +kerning = font.kerning +# and ready for your instructions. +print(kerning) +print(len(kerning)) +print(list(kerning.keys())) +# proceed to work with the myKerning object +# this happens in the following examples too. \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session3_01.py b/documentation/examples/talks/helpneeded/session3_01.py new file mode 100644 index 00000000..f5134f22 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session3_01.py @@ -0,0 +1,23 @@ +# robothon06 +# work with kerning 2 + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") +kerning = font.kerning + +# calculate the average offset +print(kerning.getAverage()) + +# count pairs with these glyphs +print(kerning.occurrenceCount(["a", "b"])) + +# get the maximum values +print(kerning.getExtremes()) + +# count the pars +print("font has %d kerning pairs" % len(kerning)) + +# this prints all the pairs +for (left, right), value in list(kerning.items()): + print((left, right), value) \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session3_02.py b/documentation/examples/talks/helpneeded/session3_02.py new file mode 100644 index 00000000..d11f73b4 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session3_02.py @@ -0,0 +1,12 @@ +# robothon06 +# work with kerning 3 +# print a specific set of pairs + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") +kerning = font.kerning + +for left, right in list(kerning.keys()): + if kerning[(left, right)] < -100: + print(left, right, kerning[(left, right)]) \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session3_03.py b/documentation/examples/talks/helpneeded/session3_03.py new file mode 100644 index 00000000..ca118e3d --- /dev/null +++ b/documentation/examples/talks/helpneeded/session3_03.py @@ -0,0 +1,11 @@ +# robothon06 +# work with kerning 4 + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") +kerning = font.kerning + +for left, right in list(kerning.keys()): + if left == "acircumflex": + print(left, right, kerning[(left, right)]) \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session3_04.py b/documentation/examples/talks/helpneeded/session3_04.py new file mode 100644 index 00000000..20835c53 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session3_04.py @@ -0,0 +1,22 @@ +# robothon06 +# building a glyph from parts +# the hard way + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") + +# make a new glyph +f.newGlyph("aacute") + +# add the component for the base glyph, a +f["aacute"].appendComponent("a") + +# add the component for the accent, acute +# note it has an offset +f["aacute"].appendComponent("acute", (200, 0)) + +# set the width too +f["aacute"].width = f["a"].width + +f.update() \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session3_05.py b/documentation/examples/talks/helpneeded/session3_05.py new file mode 100644 index 00000000..42478673 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session3_05.py @@ -0,0 +1,28 @@ +# robothon06 +# Compile a new glyph from a list of accents and required anchors +# Demo of multiple accents chaining together, or "stacking". +# For this example you need to set up a couple of things +# in your test font: +# - base glyph "a", with anchor "top" and anchor "bottom" +# - glyph "dieresis" with anchor "_top" and anchor "top" +# - glyph "acture" with anchor "_top" +# - glyph "cedilla" with anchor "_bottom" + +from fontParts.world import OpenFont + +font = OpenFont("test.ufo") + +# this is a list of tuples +# each tuple has the name of the accent as first element +# and the name of the anchor which to use as the second element + +accentList = [("dieresis", "top"), + ("acute", "top"), + ("cedilla", "bottom")] + +# The accents are compiled in this order, so first +# "dieresis" connects to "a" using "top" anchor +# "acute" connects to dieresis, using the next "top" anchor + +font.compileGlyph("myCompiledGlyph", "a", accentList) +font.update() diff --git a/documentation/examples/talks/helpneeded/session6_00.py b/documentation/examples/talks/helpneeded/session6_00.py new file mode 100644 index 00000000..eae2a3e5 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session6_00.py @@ -0,0 +1,10 @@ +# robothon06 +# set font info in all fonts + +from fontParts.world import AllFonts + +for font in AllFonts(): + font.info.familyName = "MyFamily" + font.info.ascender = 700 + font.info.descender = -300 + font.update() diff --git a/documentation/examples/talks/helpneeded/session6_01.py b/documentation/examples/talks/helpneeded/session6_01.py new file mode 100644 index 00000000..2984c0a3 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session6_01.py @@ -0,0 +1,25 @@ +# robothon 2006 +# get info attributes for all fonts +# and dump them to a text file + +from fontParts.world import AllFonts +from fontParts.interface.all.dialogs import PutFile + +text = [] + +for font in AllFonts(): + text.append(str(font.path)) + text.append(str(font.info.familyName)) + text.append(str(font.info.styleName)) + text.append(str(font.info.fullName)) + text.append(str(font.info.unitsPerEm)) + text.append(str(font.info.ascender)) + text.append(str(font.info.descender)) + text.append('') + +text = '\n'.join(text) +path = PutFile('Save file as:') +if path: + file = open(path, 'w') + file.write(text) + file.close() \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session6_02.py b/documentation/examples/talks/helpneeded/session6_02.py new file mode 100644 index 00000000..e3f9357c --- /dev/null +++ b/documentation/examples/talks/helpneeded/session6_02.py @@ -0,0 +1,13 @@ +# robothon 2006 +# batch save as + +import os +from fontParts.world import AllFonts +from fontParts.interface.all.dialogs import GetFolder + +path = GetFolder() +if path: + for font in AllFonts(): + fileName = os.path.basename(font.path) + newPath = os.path.join(path, fileName) + font.save(newPath) \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session6_03.py b/documentation/examples/talks/helpneeded/session6_03.py new file mode 100644 index 00000000..cbf11d2a --- /dev/null +++ b/documentation/examples/talks/helpneeded/session6_03.py @@ -0,0 +1,24 @@ +# robothon 2006 +# batch interpolate + +import os +from fontParts.world import SelectFont, NewFont + +# ask for two masters to interpolate: +font1 = SelectFont("Select font 1") +font2 = SelectFont("Select font 2") +# these are the interpolation factors: +values = [.3, .6] + +for value in values: + # make a new font + destination = NewFont() + # do the interpolation + destination.interpolate(value, font1, font2, doProgress=True) + destination.update() + # make a new path + filename for the new font to be saved at: + dir = os.path.dirname(font1.path) + fileName = "Demo_%d.vfb" % (1000 * value) + # save at this path and close the font + destination.save(os.path.join(dir, fileName)) + destination.close() \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session6_04.py b/documentation/examples/talks/helpneeded/session6_04.py new file mode 100644 index 00000000..9dd184a5 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session6_04.py @@ -0,0 +1,40 @@ +# robothon06 +# ask for a folder +# find (nested) fontlab files in the folder +# open the fonts +# Demonstrates: recursive function,, dialog, os module + +import os.path +from fontParts.interface.all.dialogs import GetFolder +from fontParts.world import OpenFont + +# this function looks for fontlab files in a folder +def walk(someFolder, extension): + extension = extension.lower() + files = [] + # the os module has tools to deal with + # the operating system. This returns a list of names + # of stuff in the folder you feed it: + names = os.listdir(someFolder) + for n in names: + p = os.path.join(someFolder, n) + # if this new thing is a folder itself, + # call this function again, but now with the + # new path to check that as well. This is + # called recursion. + if os.path.isdir(p): + # add the results of the other folder + # to the list + files += walk(p, extension) + continue + # is it a file with the extension we want? + # add it then! + if n.lower().find(extension) != -1: + files.append(p) + return files + +yourFolder = GetFolder("Search a folder:") +if yourFolder is not None: + fontPaths = walk(yourFolder, ".vfb") + for path in fontPaths: + OpenFont(path) diff --git a/documentation/examples/talks/helpneeded/session6_05.py b/documentation/examples/talks/helpneeded/session6_05.py new file mode 100644 index 00000000..554082b0 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session6_05.py @@ -0,0 +1,14 @@ +# rename the selected glyphs +# in the current font to .sc + +from fontParts.world import OpenFont +f = OpenFont("test.ufo") + +for g in f: + if g.selected == 0: + continue + newName = g.name+".sc" + print("moving", g.name, "to", newName) + f.insertGlyph(g, name=newName) + f.removeGlyph(g.name) + f.update() diff --git a/documentation/examples/talks/helpneeded/session6_06.py b/documentation/examples/talks/helpneeded/session6_06.py new file mode 100644 index 00000000..894fb64c --- /dev/null +++ b/documentation/examples/talks/helpneeded/session6_06.py @@ -0,0 +1,7 @@ +# robothon 2006 +# batch generate + +from fontParts.world import AllFonts + +for font in AllFonts(): + font.generate('otfcff') \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session6_07.py b/documentation/examples/talks/helpneeded/session6_07.py new file mode 100644 index 00000000..e196fb0a --- /dev/null +++ b/documentation/examples/talks/helpneeded/session6_07.py @@ -0,0 +1,46 @@ +# robothon 2006 +# a more robust batch generator that only has one font open at the time. + +from fontParts.interface.all.dialogs import GetFolder +from fontParts.world import RFont, OpenFont +import os + +def collectSources(root): + files = [] + ext = ['.vfb'] + names = os.listdir(root) + for n in names: + if os.path.splitext(n)[1] in ext: + files.append(os.path.join(root, n)) + return files + +# A little function for making folders. we'll need it later. +def makeFolder(path): + # if the path doesn't exist, make it! + if not os.path.exists(path): + os.makedirs(path) + +def makeDestination(root): + macPath = os.path.join(root, 'FabFonts', 'ForMac') + makeFolder(macPath) + return macPath + +def generateOne(f, dstDir): + print("generating %s"%f.info.fullName) + f.generate('otfcff', dstDir) + +f = GetFolder() + +if f is not None: + paths = collectSources(f) + dstDir = makeDestination(f) + for f in paths: + font = None + print(f) + try: + font = OpenFont(f) + generateOne(font, dstDir) + finally: + if font is not None: + font.close(False) + print('done') diff --git a/documentation/examples/talks/helpneeded/session6_08.py b/documentation/examples/talks/helpneeded/session6_08.py new file mode 100644 index 00000000..d3b122b4 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session6_08.py @@ -0,0 +1,40 @@ +# robothon 2006 +# merge two fonts + +from fontParts.world import SelectFont, NewFont +from fontParts.pens.digestPen import DigestPointPen +from sets import Set + +font1 = SelectFont("Select base font") +font2 = SelectFont("Select alternate font") + +font1Names = Set(list(font1.keys())) +font2Names = Set(list(font2.keys())) + +commonNames = font1Names & font2Names +uncommonNames = font2Names - font1Names + +for glyphName in commonNames: + glyph1 = font1[glyphName] + pointPen = DigestPointPen() + glyph1.drawPoints(pointPen) + digest1 = pointPen.getDigest() + + glyph2 = font2[glyphName] + pointPen = DigestPointPen() + glyph2.drawPoints(pointPen) + digest2 = pointPen.getDigest() + + if digest1 != digest2: + print('> alt >', glyphName) + glyph3 = font1.insertGlyph(glyph2, name=glyphName+'.alt') + glyph3.mark = 1 + glyph3.update() + +for glyphName in uncommonNames: + print('>', glyphName) + glyph = font1.insertGlyph(font2[glyphName]) + glyph.mark = 60 + glyph.update() + +font1.update() \ No newline at end of file diff --git a/documentation/examples/talks/helpneeded/session6_09.py b/documentation/examples/talks/helpneeded/session6_09.py new file mode 100644 index 00000000..8e065ad9 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session6_09.py @@ -0,0 +1,9 @@ +# show the objects from the fontlab layer + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +print(f.naked()) + +g = f["A"] +print(g.naked()) diff --git a/documentation/examples/talks/helpneeded/session6_10.py b/documentation/examples/talks/helpneeded/session6_10.py new file mode 100644 index 00000000..5c9ba1e1 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session6_10.py @@ -0,0 +1,3 @@ +# show vhints for current glyph +g = CurrentGlyph() +g.naked().vhints diff --git a/documentation/examples/talks/helpneeded/session6_11.py b/documentation/examples/talks/helpneeded/session6_11.py new file mode 100644 index 00000000..edd27943 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session6_11.py @@ -0,0 +1,11 @@ +# robothon06 +# show OpenType naming records +# in the fontlab API + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +fn = f.naked() + +for r in fn.fontnames: + print(r.nid, r.pid, r.eid, r.lid, r.name) diff --git a/documentation/examples/talks/helpneeded/session6_12.py b/documentation/examples/talks/helpneeded/session6_12.py new file mode 100644 index 00000000..013d7e11 --- /dev/null +++ b/documentation/examples/talks/helpneeded/session6_12.py @@ -0,0 +1,15 @@ +# robothon06 +# show encoding + +from fontParts.world import OpenFont + +f = OpenFont("test.ufo") +fn = f.naked() + +# object containing encoding records. +# you can iterate through it by using an index. +print(fn.encoding) + +for i in range(len(fn.encoding)): + er = fn.encoding[i] + print(er, er.name, er.str) diff --git a/documentation/source/gettingstarted/index.rst b/documentation/source/gettingstarted/index.rst index 973624f5..db814f05 100644 --- a/documentation/source/gettingstarted/index.rst +++ b/documentation/source/gettingstarted/index.rst @@ -6,7 +6,7 @@ Getting Started These need to be ported and updated from RoboFab's documentation. -For a quick start, here's the sample code from the introduction ported to fontparts:: +For a quick start, here's the sample code from the introduction ported to fontParts:: from fontParts.world import OpenFont @@ -16,4 +16,4 @@ For a quick start, here's the sample code from the introduction ported to fontpa glyph.leftMargin = glyph.leftMargin + 10 glyph.rightMargin = glyph.rightMargin + 10 -Find more of the original samples at https://github.com/robotools/robofab/tree/master/Docs/Examples +Some of the original examples have been converted to fontParts. Get them at https://github.com/robotools/fontParts/tree/master/documentation/examples. Please note that not all of them print out all results and/or do something useful; you may need to flesh them out. Non-working examples have been moved to a helpneeded directory. Bear in mind that not all functionality of RoboFab made it into fontParts, so some will never work.